1

First, pardon my slightly ambiguous title; I could not find a more appropriate one:

Scenario

I am using Mongoose to fetch some data and then render them with ejs. For the sake of illustration, consider the following:

// Schema
var UserSchema = mongoose.Schema({
  Username: String,
  City: String
})
// Model
var User = mongoose.model('User', UserSchema);

From my server file:

app.get('/view', function (req, res) {
  // What I am trying to do            
  User.find({}).exec().then(vals=>{
            res.send(vals)
        })

The Problem

The above code works as intended but, to the code accessible to other files as well as making upgrades easier, I want to move it another file, then require() that file.

handler.js

// Promise: Get All Names
function FetchData(){
    return User
    .find({})
    .exec();
}

module.exports = {
    Get: function(){
        val = User.find({}).exec()
        .then(vals=>{
            // Expected to return only after the above is complete
            return vals
        })
    }

}

Then, from my server file:

var handler = require('handler')

app.get('/view', function (req, res) {
  res.send(handler.Get())
});

Unfortunately, this code does not work as intended

My thoughts

I varied the parameters and tweaked the code around a few times but am unable to figure out what is going wrong. It seems that the values from Get() is being returned even before the promise is consumed (which is puzzling).

Any help would be greatly welcomed :)

Isfaaq
  • 415
  • 1
  • 4
  • 15
  • You still cannot `return` from the outer function inside the promise callback. You need to return the promise object itself, and consume its result at the caller with `then`. Promises do not make your code synchronous, they do not make future values immediately available! – Bergi Nov 17 '17 at 15:40
  • Are there any work-around to this? – Isfaaq Nov 17 '17 at 15:43
  • No. There is no workaround that, until you invent a time machine. – Bergi Nov 17 '17 at 19:31

2 Answers2

0

I think you should be something like this:

module.exports = {
  Get: function() {
    return User.find({}).exec()
      .then(vals => {
        // Expected to return only after the above is complete
        return vals
      })
  }
}

and then

app.get('/view', function (req, res) {
  handler.Get().then((response) => {
    res.send(response);
  });
});

So, return promise from Get and then use its then API.

dfsq
  • 191,768
  • 25
  • 236
  • 258
0

Here's the code that may help you.

Change your main server file to something like this

app.get('/view', function (req, res) {
  handler.Get().then(vals => {
       res.send(vals);
  });

And in handler.js file, you can do

module.exports.Get = function(){
     return new Promise((resolve, reject) => {
          User.find({}).exec(function(err, users){
               if(!err){
                    resolve(users);
               }
          });     
     });
}
Pavan Vora
  • 1,634
  • 14
  • 19