1

I'm working on a Restful API with node.js and mongoose. I need to return an object with the results of a search. Here is my code:

var Get = function (criteria) {      
    var result;
    Users.findOne(criteria, function(err, res){
        console.log('Error: ' + err);
        console.log('Results: ' + res);
        result = err || !res ? err || errors['404']: res;
        console.log(result);
    });
    console.log('Final results: ' + JSON.stringify(result));
    return result;
};

Since I was having problems, I added those console.logs to watch where the result is lost. Here are the logs:

Final results: undefined Error: null Results: { //user... }

I need that result to be returned. How can I solve this?

Stennie
  • 63,885
  • 14
  • 149
  • 175
Leo
  • 449
  • 2
  • 17
  • [How to return the response from an asynchronous call?](http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-asynchronous-call) – Jonathan Lonowski Apr 17 '15 at 16:18
  • 1
    Note: A future possible option will be using [`await`](https://github.com/tc39/ecmascript-asyncawait) with functions that use [ES6 `Promise`s](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise), provided MongoDB's client API begins using those. – Jonathan Lonowski Apr 17 '15 at 16:25

1 Answers1

2

This is one of the most asked questions in the history of the internet!

Since node is asynchronous you'll need to rewrite the function to return a callback or use something like promises.

Here it is with callbacks:

var Get = function (criteria, cb) {      
    return Users.findOne(criteria,cb);  
};

And then call it like:

Get({}, function(err, res){
  console.log(res);
});

Or you can use promises, here it is using the Q library

var Get = function (criteria) {   

var deferred = Q.defer();
 Users.findOne(criteria,function(err, o){
       if (err) deferred.reject(err);
            deferred.resolve(o);
 });
 return deferred.promise;
}

And then call it like this:

Get({}).then(function(res){console.log(res)});

The promise based version seems more complicated to me :).

Robert Moskal
  • 21,737
  • 8
  • 62
  • 86
  • Is there anything else I can do? I had that and my code was very messy. – Leo Apr 17 '15 at 16:11
  • No, node is asynchronous, and it's either promises or callbacks all the way down:). The callback based code seems elegant to me:) – Robert Moskal Apr 17 '15 at 16:19
  • It is elegant, but in some part I have to see if there is an error or there is no result in every function with the database I have. But thanks! That solve my question. :) – Leo Apr 17 '15 at 16:22
  • 2
    Note: Promises have [native support](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) with Node.js 0.12 and io.js (or via the `--harmony` flag in some previous versions). – Jonathan Lonowski Apr 17 '15 at 16:31