Установка объекта в req. в первой из двух промежуточных программ, похоже, отсутствует во время вызова второго промежуточного программного обеспечения

#javascript #mongodb #express #mongoose

#javascript #mongodb #экспресс #mongoose

Вопрос:

У меня есть два промежуточных ПО express, где одно устанавливает объект для запроса, а другое, которое следует за ним, использует этот объект для включения оператора switch .

Вот иллюстрация:

 module.exports = (req, res, next) => {
  if (!req.headers.authorization) {
    return res.status(401).end()
  }
  const token = req.headers.authorization.split(' ')[1]
  return jwt.verify(token, config.database.jwtSecret, (err, decoded) => {
    if (err) { return res.status(401).end() }

    const userId = decoded.sub
    return User.findById(userId, (userErr, user) => {
      if (userErr || !user) {
        return res.status(401).end()
      }
      req.user = {
        _id: user._id,
        name: user.name
      }
      return next()
    })
  })
}

    //My route
        userpage.get('/', authCheck, (req, res) => {
          return Event.findOne()
          .populate('attending.user', 'name') 
          .exec((err, newEvent) => {
            if (err) {
              console.log(err)
              res.status(400).end()
            }
            let uids = []
            let imAttending = false
            newDinner.attending.user.map(obj => {
              uids.push(obj._id)
              })
            console.log(uids) // Shows the array with all uids
            // Double checked that it is indeed an array
            let isArr = Object.prototype.toString.call(uids) === '[object Array]'
            console.log(isArr) // true
            console.log(req.user._id) // Shows the id and it's indeed matching one of the ids in the uids array
            imAttending = uids.indexOf(req.user._id) > -1
            console.log(imAttending)  // false <--- Should be true
            // Test
            let id = '57ec2203ba3e994c7c9d5832' // I litraly copy pasted that from the console.log(req.user._id)
            imAttendingII = uids.indexOf(id) > -1
            console.log(imAttendingII) // true ???? what the heck?
            // checking it's the same type as suggested in one of the comments
            let check = ['57ec2203ba3e994c7c9d5832'].indexOf(req.user._id) === -1
            console.log(check) //true
          })
        })
  

Приведенные ниже комментарии убедили меня, что это не проблема с асинхронностью, и, следуя результатам, которые я получаю, я теряюсь в том, что это может быть.

Редактировать: однако следующее работает и показывает true. Но проверка полей _id не работает даже после выполнения uids.indexOf(req.user._id.toString()) > -1 над элементом _id:

 newEvent.attending.user.map(obj => {
      names.push(obj.name)
    })
    imAttending = names.indexOf(req.user.name) > -1 // imAttending = true
  

Комментарии:

1. Похоже, вы хотите вызвать next() в первом промежуточном программном обеспечении из разрешенного обещания

2. Промежуточное программное обеспечение не будет передаваться следующему промежуточному программному обеспечению до тех пор, пока не будет вызвана следующая функция. Поскольку вы вызываете его только при обратном вызове функции async, он уже должен ожидать установки req.user, прежде чем переходить к следующему обработчику.

3. Ваш код, который вы показываете прямо сейчас, будет вызываться только next() после завершения обхода базы данных и настройки req.user свойства. Смотрите Мой ответ ниже, это может быть проблемой в другом месте.

4. Это тоже то, о чем я думал, но если вы следите за моим редактированием, я просто не мог объяснить результаты, проиллюстрированные там каким-либо другим способом, кроме как асинхронным.

5. @S.Schenk Вы уверены, что req.user._id и элементы идентификаторов uid имеют один и тот же тип? Например: [‘12345’].indexOf(12345) === -1. Вы пытались использовать req.user. _id в строку перед выполнением indexOf? uids.indexOf(» req.user._id) ?

Ответ №1:

Решил добавить еще один ответ из-за дополнительной информации, представленной в вопросе.

Похоже, вы используете MongoDB и Mongoose (которые должны быть в тегах, если я прав). Учитывая это, _id свойство пользовательского документа не будет равно его строковой форме, потому что представление на самом деле ObjectID('blahblahblah') , на самом деле это не строка под капотом. Если вы console.log() это сделаете, это будет выглядеть как строка, потому что консоль.регистрируйте вызовы toString() под его капотом.

Итак, оценка, которую вы, возможно, захотите попробовать, такова:

 imAttending = uids.indexOf(req.user._id.toString()) > -1;
console.log(imAttending); // should be true
  

В качестве дополнительного примечания, именно поэтому это отличная причина использовать что-то вроде node-inspector установки точек останова и пошагового выполнения вашего кода, а не полагаться на консольные инструкции для отладки. Вы увидите фактическое представление различных битов, а не их строковую форму.

Комментарии:

1. Я пробовал, и он по-прежнему false, что крайне странно, потому что, когда я переключился на проверку соответствия имени, которое является другим параметром, который я устанавливаю для объекта req.user, он работает просто отлично. Может быть, мне также нужно превратить список идентификаторов, которые я добавляю в массив uids, в строки? О, и да, я использую mongoose, я добавлю это в теги.

2. Я чувствую, что проблема может на самом деле заключаться в uid переменной, при отображении через newDinner mongo, возможно , сохранил _id свой собственный уникальный идентификатор. Так что, может toString() быть, его использование поможет решить эту проблему?

3. Ну, в любом случае @S. Шенк, вам нужно проверить значения, которые вы сравниваете в точке сравнения (включая проверку типов), чтобы узнать, что происходит и почему они не равны. например, моя рекомендация использовать node-inspector .

4. Я получаю TypeError: не удается прочитать свойство ‘ref’ неопределенного значения с помощью npm-inspector, поэтому сейчас я использую: let check = typeof(req.body._id) === ‘string’

Ответ №2:

С самого начала это была проблема с toString() . Результаты, которые вы получаете от запроса к БД, не обязательно того типа, который, по вашему мнению, может быть.