4

I am new to mongoose. Here is my scenario:

var childSchema = new Schema({ name: 'string' });
var parentSchema = new Schema({
children: [childSchema]});
var Parent = mongoose.model('Parent', parentSchema);

Say I have created a parent 'p' with children, and I am querying for 'p', using

var query = Parent.find({"_id":"562676a04787a98217d1c81e"});
query.select('children');                                   
query.exec(function(err,person){                            
    if(err){                                                    
        return console.error(err);                               
    } else {                                                     
        console.log(person);                                     
    }
});                                                    

I need to access the person object outside the async function. Any idea on how to do this?

2 Answers 2

5

Mongoose's find() method is asynchronous which means you should use a callback that you can wrap the query from the find() method. For example, in your case, you can define a callback as

function getChildrenQuery(parentId, callback){
    Parent.find({"_id": parentId}, "children", function(err, docs){
        if (err) {
          callback(err, null);
        } else {
          callback(null, docs);
        }
    }); 
}

which you can then call like this:

var id = "562676a04787a98217d1c81e";
getChildrenQuery(id, function(err, children) {
    if (err) console.log(err);

    // do something with children
    children.forEach(function(child){
      console.log(child.name);
    });
});

Another approach you may take is that of promises where the exec() method returns a Promise, so you can do the following:

function getChildrenPromise(parentId){
   var promise = Parent.find({_id: parentId}).select("children").exec();
   return promise;
}

Then, when you would like to get the data, you should make it async:

var promise = getChildrenPromise("562676a04787a98217d1c81e");
promise.then(function(children){
    children.forEach(function(child){
        console.log(child.name);
    });
}).error(function(error){
    console.log(error);
});
Sign up to request clarification or add additional context in comments.

Comments

0

you cannot access it outside of the callback (="the async function" you mentioned). That's how node.js works:

  • your call to the database will take some time - a very long time when you compare it to just execute a simple code statement.
  • Node.js is non-blocking, so it will not wait for the database to return the result, and it wlll continue immediately by executing the code after your query.exec statement.
  • so the code you write after the query.exec statement is run BEFORE the database returns the result, it is therefore impossible to use that result there.

BUT... embrace async programming:

  • just write all the code you need into the "async function"
  • pass a callback into your function, call it from "the async function" and pass it the query result

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.