Kamil Turowski
Kamil Turowski

Reputation: 465

Mongoose assign findOne() result to variable

I have a function:

function RetrieveCountryCode(countryName, callback) {
  Country.find({ name: countryName }, function(err, country) {
    if (err) {
      callback(err, null);
    } else {
      callback(null, country.code);
    }
  });
}

I am using it like this:

//find a country code of a given country by user
var userCountryCode = null;
RetrieveCountryCode(country, function(err, countryCode) {
  if (err) {
    console.log(err);
  }
  userCountryCode = countryCode;
});
console.log("COUNTRY CODE");
console.log(userCountryCode);

*Parameter 'country' given to a function is from html form, it's passed correctly, I checked it.

And I still get the same response in console: COUNTRY CODE null. What am I doing wrong...?

Upvotes: 0

Views: 1218

Answers (1)

kevinadi
kevinadi

Reputation: 13765

As Suleyman said in the comments, this is due to node's async nature. The flow of the code is not like what you expect. There are a lot of tutorial on the internet regarding node's async nature, and I suggest you understand them and experiment with them since it's not very intuitive at first.

Due to this, the console.log(userCountyCode) was executed before RetrieveCountryCode() can finish its work.

The solution is to put the console.log(userCountyCode) inside the callback.

For example, if my collection contains:

> db.countries.find()
{ "_id" : ObjectId("5dc4fcee86c118c901a7de35"), "name" : "Australia", "code" : "61", "__v" : 0 }

Using a modified version of the code you have:

var userCountryCode = null;
var country = 'Australia';

mongoose.connect(url, opts)

function RetrieveCountryCode(countryName, callback) {
  Country.findOne({ name: countryName }, function(err, country) {
    if (err) {
      callback(err, null);
    } else {
      callback(null, country.code);
    }
  });
}

RetrieveCountryCode(country, function(err, countryCode) {
  if (err) {
    console.log(err);
  }
  userCountryCode = countryCode;
  console.log("COUNTRY CODE");
  console.log(userCountryCode);
});
console.log('xxx');

Note that I didn't change the definition of the RetrieveCountryCode function at all. I just changed how it's called and moved the console.log inside the callback. I put console.log('xxx') in its place instead.

Running this code outputs:

xxx
COUNTRY CODE
61

Note that xxx was printed before the country code since it was executed before the callback prints the result of the query.

In conclusion, your code always prints null because:

  1. You print the variable content before it was filled by the query.
  2. You didn't print the variable content inside the callback.

Note: I changed the find() in your code to findOne(). I believe the find() is a typo on your part.

Upvotes: 1

Related Questions