0

I have this endpoint in node js and express, that adds students to an array. I pass the class name and an array of emails in the body of the request. The logic goes as follows:

  • Search whether the class exists using the class name passed. If the class exists then iterate through the array of emails, searching whether a user with the email exists and has role member. If they satisfy that, then add them to the array.

The problem:

  • When I try to console log the array inside the loop it shows me that the student object was added to the array. However, when outside the loop, I get an empty array on console.log

Here's the actual code I'm trying to describe:

const findClass = LessonClass.findOne({className: req.body.className}).exec();
findClass.then(classObject => {
       // check that each emails exists and has role member
       const studentArray = [];
       const emailBody = req.body.email;
       emailBody.forEach(email => User.findOne({email}).exec().then(userObject => {
           if(userObject.role !== 'member'){
               return res.status(400).send({
                   error: 'Only users with role member can be added to a class as students'
               });
           }
           const student = {
               email: userObject.email,
               studentName: userObject.firstName + ' '+ userObject.lastName
           };
           // add the student to the student array
           studentArray.push(student);
           console.log(studentArray); // returns student object inside array
       })
           .catch(err => {
               console.log(err);
           }));
         console.log(studentArray) //returns empty array
   })

Anyone help?

2
  • Your code is async and the second console.log(studentArray) is called firsts (before your async request done). You can access file array inside .then. Or you can try to use async Commented Mar 20, 2019 at 15:04
  • Thanks @Pvl. Makes sense Commented Mar 20, 2019 at 15:23

1 Answer 1

1

Because your code might be still adding students when you logged them out see this code

const findClass = LessonClass.findOne({ className: req.body.className}).exec();
findClass.then(classObject => {
  // check that each emails exists and has role member
  const studentArray = [];
  const emailBody = req.body.email;
  emailBody.forEach(email => User.findOne({email}).exec()
    .then(userObject => {
      if (userObject.role !== 'member') {
        return res.status(400).send({
          error: 'Only users with role member can be added to a class as students'
        });
      }
      const student = {
        email: userObject.email,
        studentName: userObject.firstName + ' ' + userObject.lastName
      };
      // add the student to the student array
      studentArray.push(student);
      console.log(studentArray); // returns student object inside array
      return studentArray;
    })
    .then(students => {
      console.log(students);
    }));
})

What I have done is, I removed your console.log and chained it with second then and from your first then returned the students array.

In javascript the callbacks are non blocking, i.e. they won't block the sequence of execution and control will go to next statements. When you declared the studentsArray and initiated the non sync operation (promise) it didn't wait for the execution to complete and went straight to console.log statement.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks @Umair Abid. Makes much sense and worked for me

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.