0

I'm getting this array of user emails from the post data. I want to find the _id related to each email. I tried this for loop:

var studentIds = [];

for (var i = studentEmails.length - 1; i >= 0; i--) {
  var email = studentEmails[i];

  User.findOne({"email": email}, (err, student) => {
    if (err) {
      console.log("ERROR" + err);
    }
    if (student) {
      var id = student._id;
      studentIds.push(id);
      console.log("STUDENT: " + student);
    }
  });

}

// Outside for loop
console.log('END');

However, this logs the following:

END
STUDENT: { _id: 5a11e667d7333203337cd9a4,
  name: 'Patrick Jacobs',
  email: 'windvaan@live.nl',
  password: '$2a$10$CiSw/VH1HCaPtW6Sjz0X4.4avVoLsAH6iyF3FhidorahwLt1WDXoC',
  __v: 0 }
STUDENT: { _id: 5a0f7dfb64b5a6000417c662,
  name: 'Carlo Jacobs',
  email: 'carlojacobs91@gmail.com',
  password: '$2a$10$fiIosS4Jo5ehuCp3TfltSOnpypPMWSMvzlb7phRWmNGBtDz5W1rCG',
  __v: 0 }

As you can see, the END is being printed first. I don't want that. I'm assuming the for loop is asynchronous? How can I make it synchronous?

Thx in advance!

2 Answers2

0

It is not the for loop, but the User.findOne call that is asynchronous.

Following this answer, you could use streamline.js; try the following to make the call synchronous.

var result = User.findOne({"email": email}, _);
if (result === null) {
      console.log("ERROR" + err);
}

var id = result._id;
studentIds.push(id);
console.log("STUDENT: " + result);
Matt Clark
  • 27,671
  • 19
  • 68
  • 123
0

The solution would be

var studentIds = [];
var loopRecords = function (records, cb) {
 if (!records.length) return cb();
 var email = records.shift();
 User.findOne({"email": email}, (err, student) = > {
    if (err) {
        console.log("ERROR" + err);
    }
    if (student) {
        var id = student._id;
        studentIds.push(id);
        console.log("STUDENT: " + student);
    }
    return loopRecords(records, cb);
 }
}

loopRecords(studentEmails,function () {
  console.log('END');
})
Satpal Tanan
  • 1,108
  • 7
  • 17