Chri5
Chri5

Reputation: 1

Async / Await with NodeJS + Mongoose doesn't wait

Cannot get the async / await functions to work properly in my card game app.

(a) I get the 201 response with no data.

(b) the deck document seems to be created afterwards, with the players field an empty array, indicating it is done after the deck is saved to the mongoDB

Below is my code. Any help is appreciated.

router.js

router.post('/game', (req, res, next) => {
  try {
    const { cards, playerNames, attributes } = req.body;

    const newDeck = deck.start(cards, playerNames, attributes);
    res.status(201).send(newDeck);
  } catch (err) {
    next(err);
  };
});

/services/deck.js

 exports.start = async (cards, playerNames, attributes) => {
  try {
    const users = await user.create(playerNames);

    const deck = new Deck({
      cards,
      attributes,
      players: users
    });

    return await deck.save((err, newDeck) => {
      if (err) console.log(err);
      console.log('RESULT', newDeck);
    });
  } catch (err) {
    console.log(err);
  }
};

/services/user.js

exports.create = async (users) => {
  if (users.constructor === String) {
    const user = new User({displayname: users});

    return await user.save((err, newUser) => {
      if (err) console.log(err);
      console.log('NEW USERS ', user);

      return newUser;
    });
  } else if (users.constructor === Array) {
    let userList = [];

    await users.forEach(name => {
      const user = new User({displayname: name.toString()});

      return user.save((err, newUser) => {
        if (err) {
          console.log(err);
        } else {
          userList.push(newUser);
          return newUser;
        }
      });
    });
    console.log('NEW USERS ', userList);

    return userList;
  };
};

Upvotes: 0

Views: 141

Answers (1)

Mohammed Yousry
Mohammed Yousry

Reputation: 2184

I am not familiar how you're handling promises,

but forEach is not promise-aware, that's how it has been designed, so it will not handle your asynchronous code properly

replace it with normal for loop or for-of loop, and add the await keyword in front of the user.save() method

Upvotes: 1

Related Questions