How to return query results to a variable using mongoose

16,901

Solution 1

When Node has to do any I/O, like reading from a database, it will be done asynchronously. Methods like User.findOne and Query#exec will never return a result upfront so article.owner will not be properly undefined in your example.

The result of an asynchronous query will only be available inside of your callback, which is only invoked when your I/O has finished

article.owner = User.findOne({ name : 'ABC' }) .exec(function (err, user){    
    // User result only available inside of this function!
    console.log(user) // => yields your user results
})

// User result not available out here!
console.log(article.owner) // => actually set to return of .exec (undefined)

What asynchronous code execution means in the above example: When Node.js hits article.owner = User.findOne... it will execute User.findOne().exec() and then move straight onto console.log(article.owner) before .exec has even finished.

Hope that helps clarify. It takes a while to get used to async programming it but it will make sense with more practice

Update To answer your specific problem, one possible solution would be:

User.findOne({name: 'ABC'}).exec(function (error, user){
    article.owner = user._id; // Sets article.owner to user's _id
    article.save()            // Persists _id to DB, pass in another callback if necessary
});

Remember to use Query#populate if you want to load your user with the article like so:

Article.findOne({_id: <some_id>}).populate("owner").exec(function(error, article) {
    console.log(article.owner); // Shows the user result
});

Solution 2

User.findOne({ 'name' : 'ABC' }) .exec(function (err, user){
    article.owner = user.fieldName;
})

Solution 3

The answer by hexacyanide shows how to carry data from the async db find callback via another callback. Saved me for my project!

Set Variable to result of Mongoose Find

Share:
16,901
Admin
Author by

Admin

Updated on June 14, 2022

Comments

  • Admin
    Admin almost 2 years

    I am still in learning stage of Node.js and Moongoose and i have a scenario where in

    • I am taking value(ABC) from form submit.It is a user's Name
    • Then i am searching for that name in users collection(User)
    • Fetch that user and write its ObjectID in another schema(article) using ref.

    My logic:

    article.owner = User.findOne({ 'name' : 'ABC' })
        .exec(function (err, user){
             return user
        })
    

    But it is not returning results. I referred some other answers and tried async.parallel but still i am not able to save ABC user's objectID in article schema at article.owner i am always getting null.

    Please suggest me any other better ways.

  • Admin
    Admin over 10 years
    Thanks for the quick answer C Blanchard :-) But this answer did not solve my basic question of how to get Username into my other collection(article) where i need to assign this user's objectID at article.owner using ref. Kindly let me know if you need still more details
  • C Blanchard
    C Blanchard over 10 years
    damphat's earlier response was the answer to your solution, I just wanted to help you understand his answer. I'll update my answer in any case since there's more information about the problem
  • michaelAdam
    michaelAdam over 9 years
    So if you added "console.log(article.owner);" outside of that function, it would print user.fieldName?
  • damphat
    damphat over 9 years
    no michaelAdam, console.log must be inside, or you can use npm 'async' to wait for a callback