A
A
angelzzz2019-08-20 14:10:47
JavaScript
angelzzz, 2019-08-20 14:10:47

How to call mongoose findOne inside forEach while waiting for a response?

I have an array, I iterate through it with forEach and check the type of each value. For one type, I need to make a request to mongoDB, wait for a response, and only then go further through the array.
If it matters - I then use these values ​​and the result to call socket.io emit inside setTimeOut.
Here is an iteration example:

questionList.forEach((question) => {
    let respName = "";
    let respObj = question;

    if (question.type === "some_type") {
      // some not important code
      // respName = "some_name" 
    } else if (question.type === "some_typeN") {
      // some not important code
      // respName = "some_nameN"
    } else if (question.type === "some_type4") {
      respName = "some_name4"
      respObj = getBlockStats(handle, block);
    } else {
      // some not important code
      // respName = "some_nameX"
    }

    setTimeout(() => {
      io.emit(respName, respObj);
    }, offset);

    offset += offsetIncrease;
});

Here is the function I call to access the database:
const getBlockStats = (handle, block) => {
  return GameAnswers.findOne({ handle })
    .then(gameAnswers => {
      let maxQuesstionInBlock = gameAnswers.answers
        .reduce((a, b) => {
          return (parseInt(a.ownId) > parseInt(b.ownId) ? a : b)
        })
      let results = [];

      for (let i = 1; i <= maxQuesstionInBlock.ownId; i++) {
        let team1AllAnswers = gameAnswers.answers
          .filter(el => el.blockId === block)
          .filter((el) => el.team === "team1")
          .filter((el) => parseInt(el.ownId) === i);

        let team1CorrectAnswers = team1AllAnswers
          .filter(el => el.correct === "true");

        let team2AllAnswers = gameAnswers.answers
          .filter(el => el.blockId === block)
          .filter((el) => el.team === "team2")
          .filter((el) => parseInt(el.ownId) === i);

        let team2CorrectAnswers = team2AllAnswers
          .filter(el => el.correct === "true");

        let result = {
          "question": i,
          "team1": {
            "all": team1AllAnswers.length,
            "correct": team1CorrectAnswers.length,
            "percent": team1CorrectAnswers.length * 100 / team1AllAnswers.length
          },
          "team2": {
            "all": team2AllAnswers.length,
            "correct": team2CorrectAnswers.length,
            "percent": team2CorrectAnswers.length * 100 / team2AllAnswers.length
          }
        }

        results.push(result);

      }
      return results;
    })
    .catch(err => {
      console.log("no GameAnswers find err -> ", err);
    });
}

From the logs, I see that my mongoDB request occurs after forEach passes through the weight of the array. For some_type4 , the value of respObj is an empty object.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Anton Shvets, 2019-08-20
@angelzzz

https://developer.mozilla.org/en-US/docs/Web/JavaS...

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question