Aleski
Aleski

Reputation: 1442

Mongoose model saves without array

I'm still trying to get my head out of SQL mode, which may be the reason this is an architectural issue rather than an implementation one but I can't for the life of me figure out how to accomplish the functionality I am trying to attain.

I have a schema, for users. It saves the users to the mongoDB using mongoose without any hassle. It contains generic stuff along the lines of username, password, etc.

However we have a new property to enter into the schema model, this is called achievements and is an array of achievements from another schema. It is declared in the users schema as follows:

var UserSchema   = new Schema({
  _id               : { type: String, unique: true },
  group_id          : { type: String, required: true },
  username          : { type: String, required: true },
  achievements      : { type: Array }
});

On the UserSchema.save, I am looking up the Achievements model to get an array of achievements that match the same group_id, as follows:

exports.create = function(req, res, next) {
  var newUser = new User(req.body);

  // Populate the achievements (same group_id)
  Achievement.find()
    .where({ group_id: newUser.group_id })
    .select({ _id: 1 })
    .exec()
    .then(function(achievementsForGroupArray) {

      _.forEach(achievementsForGroupArray, function(achievementForGroup) {
        newUser.achievements.push(achievementForGroup);
      });
    })
    .catch(function(err) {
      return res.status(400).send(err).end();
    })

  newUser.save(function(err, user) {
    // .. generic validation stuff ..
  }

Now, above, even when replacing the forEach() with a straight push of the returned array doesn't work and even replacing the push with simply pushing 'test' still doesn't populate it.

When I console.log newUser before the save, they are in there. When I console.log the user part of newUser.save(function(err, user) there is no achievements.

Is my schema setup incorrectly so Mongoose/MongoDB is just dropping it because it doesn't match the correct type?

EDIT: I am certain there are results as when I console log them, I can see them inside the foreach.

Upvotes: 0

Views: 83

Answers (1)

Sachin
Sachin

Reputation: 2922

You are stuck in the asynchronous behaviour. Put your newUser.save method inside "then block"(after forEach)

exports.create = function(req, res, next) {
  var newUser = new User(req.body);

  // Populate the achievements (same group_id)
  Achievement.find()
    .where({ group_id: newUser.group_id })
    .select({ _id: 1 })
    .exec()
    .then(function(achievementsForGroupArray) {

      _.forEach(achievementsForGroupArray, function(achievementForGroup) {
        newUser.achievements.push(achievementForGroup);
      });
 **newUser.save(function(err, user) {
    // .. generic validation stuff ..
  })**
    })
    .catch(function(err) {
      return res.status(400).send(err).end();
    })

Upvotes: 1

Related Questions