Ad

Sails.js How To Pass To View Variables From Multiple Models

- 1 answer

everyone, I am learning sails.js, and have a question (here's my code in the controller):

var test;
User.find().exec(function callBack(err,results){
                    //console.log(results);
                      test = results; //not working;
                    });

Reminder.find().exec(function callBack(err,reminders){
                    });

I want to pass the results from the two queries to my view:

return res.view('reminder/bla', 
    {
        users: users,
        reminders: reminders
    });

Any suggestions?

Ad

Answer

This is pretty ugly but it will work. Yes, you would be better off doing this in parallel (concurrently) & NPM modules such as async, or a promises library using (eg. Q.All) could help here. But if you are just stuck and wish to get this out the door just nest them inside each other.

Warning - this will execute one after the other.

// entry inside Controller method here..

var test;
User.find().exec(function callBack(err, users){

  Reminder.find().exec(function callBack(err, reminders){

    return res.view('reminder/bla',
      {
        users: users,
        reminders: reminders
      });

  });

});

One approach to do the above concurrently would be to use async.parallel - of the form of:

async.parallel([
    function(){ ... },
    function(){ ... }
], callback);

Another approach is to use a Promises library. SailsJS uses BlueBird (since version 0.11.0), and earlier versions used Q.

Q.All is of the form of:

    return Q.all([
        promise1,
        promise2
    ]).spread(function (resultFromPromise1, resultFromPromise2) {
      // do something with the results...
});

You could easy use one of the above approaches to parallelise the User.find() and Reminder.find() function calls such that they execute concurrently.

I don't have your code sample / Sails instance open so won't hazard trying to write the specific syntax in this answer. However, if you try to use one of the approaches above and get stuck, then please update your question and will be happy to take a look.

Simple illustration of each approach as follows (using simple logic for demo only)

Using Async.js

var async = require('async');

var task = function (cb, count) {
  setTimeout(function () {
    cb(null, "complete: " + count);
  }, 1000);
};

async.parallel([
  function (cb) {
    task(cb, 'one');
  },
  function (cb) {
    task(cb, 'two');
  }
], function (err, results) {
  console.log(results);
  //[ 'complete: one', 'complete: two' ]
});

Using Q:

var Q = require('q');

function task1(cb, count) {
  var deferred = Q.defer();
  setTimeout(function () {
    return deferred.resolve(cb(null, count));
  }, 1000);
  return deferred.promise;
}

var myCb = function (err, count) {
  return "complete: " + count;
};

Q.all([task1(myCb, 'one'), task1(myCb, 'two')])
  .then(function (results) {
    console.log(results);
    //[ 'complete: one', 'complete: two' ]
  });
Ad
source: stackoverflow.com
Ad