Модель мангуста получает неопределенные свойства после населения

У меня возникла проблема с базовым запросом. Все свойства модели мангуста, которые я извлекаю, не определены в обратном вызове exec().

Вот моя схема:

userSchema: new Schema({
    email: { type: String, limit: 50, index: true },
    password: String,
    birthdate: { type: Date },
    active: { type: Boolean, default: true },
    friends: [{
      _friend: { type: Schema.ObjectId, ref: 'User' },
      addedDate: { type: Date, default: Date.now }
    }],
    registrationDate: { type: Date, default: Date.now }
  })

Вы уже можете заметить, что мое свойство «friends» представляет собой массив объектов, ссылающихся на другую схему.

Теперь вот мой запрос:

dbModels.User
.find({ _id: req.session.user._id })
.populate('friends._friend', 'email birthdate')
.exec(function (err, _user){
  if (err || !_user){
    apiUtils.errorResponse(res, sw, 'Error when fetching friends.', 500);
  } else {

    console.log('user', _user);
    // This output the object with all its properties

    console.log('user birthdate', _user.birthdate);
    // _user.birthdate is undefined

    console.log('user friends', _user.friends);
    // _user.friends is undefined

    apiUtils.jsonResponse(res, sw, _user);
  }
});

Когда эта веб-служба возвращает «_user», все свойства хорошо определены и имеют правильные значения. Проблема в том, что я хочу вернуть только _user.friends, что невозможно, поскольку оно не определено.

Теперь вот функция apiUtils.jsonResponse:

exports.jsonResponse = function (res, sw, body) {

  console.log(body.friends);
  // At this breakpoint, body.friends is still undefined

  (sw || _sw).setHeaders(res);
  if (util.isArray(body)) {
    for (var i = 0; i < body.length; i++) {
      body[i] = exports.cleanResults(body[i]);
    }
  } else {

    console.log(body.friends);
    // At this breakpoint body.friends is still undefined

    body = exports.cleanResults(body);
  }
  res.send(httpCode || 200, JSON.stringify(body));
};

И функция cleanResults:

exports.cleanResults = function (body) {

  console.log(body.friends);
  // At this point, body.friends is FINALLY DEFINED

  if (typeof body.toObject === 'function') {
    body = body.toObject();
    delete body.__v;
  }

  for (var attr in body) {
    if (body.hasOwnProperty(attr) && attr[0] == '_') {
      var _attr = attr.replace('_', '');
      body[_attr] = body[attr];
      delete body[attr];
    }
  }
  return body;
};

Я попытался установить тайм-аут, чтобы увидеть, возникла ли проблема из-за асинхронности, но это ничего не изменило. В настоящее время я немного в отчаянии, и я хотел бы знать, сталкивались ли вы уже с такой же проблемой раньше?


person cocoggu    schedule 14.09.2014    source источник
comment
правильно ли друг отображался в console.log всего пользовательского объекта? Вы записали в console.log объект друзей повсюду, и в методе cleanResults он вывел неопределенное ожидание?   -  person Mattias Farnemyhr    schedule 15.09.2014
comment
Привет материк и спасибо тебе. Когда я печатаю весь пользовательский объект, user.friends уже заполняется, все в порядке. Да, я выводил user.friends в каждом из своих комментариев, и он был неопределенным до метода cleanResults.   -  person cocoggu    schedule 15.09.2014
comment
Ok. дай мне минутку. попробую воспроизвести.   -  person Mattias Farnemyhr    schedule 15.09.2014
comment
нашел проблему: см. мой ответ.   -  person Mattias Farnemyhr    schedule 15.09.2014


Ответы (1)


Я вижу вашу проблему, вы случайно использовали find, когда ожидаете, что будет возвращен только один объект. В этом случае вы должны использовать findById:

User
    .findById(req.session.user._id)
    .populate('friends._friend', 'name surname picture birthdate')
    .exec(function(err, user) {
        ...
    })
person Mattias Farnemyhr    schedule 15.09.2014
comment
Большое спасибо, это работает как шарм !! Я не могу понять, почему find не работает, поскольку некоторые запросы могут ожидать возврата одного или нескольких объектов... - person cocoggu; 15.09.2014
comment
find вернет список пользователей, вы могли бы использовать find к тому времени, когда вы добавите пользователей, и вам нужно было получить одного из пользователей, например: var user = users[0] или что-то в этом роде. - person Mattias Farnemyhr; 15.09.2014
comment
аааа, я не заметил скобок массива, когда печатал весь пользовательский объект. Спасибо !!! - person cocoggu; 15.09.2014