Понимание проблемы
Ошибка в том, что find()
извлекает массив и findOne()
извлекает объект.
посмотрите на:
Collections.find({ ... }, arg1 => { ...
Collections.findOne({ ... }, arg2 => { ...
В Пример выше arg1
- это массив, свойство user
не существует в массиве. Следовательно, arg1.user
должно вернуть undefined
. Теперь понятно, почему ошибка:
"Error: TypeError: Cannot read property 'toString' of undefined"
, если arg1.user
равен undefined
, вы не можете позвонить arg1.user.toString()
.
Но в приведенном выше примере arg2
- это объект mov ie, обладающий свойством user
, и оператор arg2.user.toString()
прекрасно работает.
Проблема понятна, теперь давайте исправим ее.
Исправление без изменений слишком много:
router.get("/movies/:user", requireAuth, (req, res) => {
User.findOne({ id: req.user.id }).then(user => {
Collections.find({ user: req.params.user })
.then(collections => {
const data = collections.filter(c => c.user.toString() === req.user.id);
res.json(data);
})
.catch(err => res.status(400).json("Error: " + err));
});
});
Лучший подход МОЖЕТ быть (при условии, что вы пытаетесь отправить все фильмы, которые соответствуют пользователю):
router.get("/movies/:user", requireAuth, (req, res) => {
if (req.params.user !== req.user.id) {
return res.status(401).json({ notauthorized: "User not authorized" });
}
Collections
.find({ user: req.params.user })
.then(collections => {
res.json(collections);
})
.catch(err => res.status(400).json("Error: " + err));
});
Или даже лучше: (при условии, что вы необходимо отправить все фильмы, которые может видеть зарегистрированный пользователь):
router.get("/movies/logged-user", requireAuth, (req, res) => {
Collections
.find({ user: req.user.id })
.then(collections => {
res.json(collections);
})
.catch(err => res.status(400).json("Error: " + err));
});
В приведенном выше фрагменте /movies/:user
был изменен на /movies/logged-user
Когда :
используется на express url, express сделает параметр роутера. Проверьте Express API Reference для получения дополнительной информации.
Это: /movies/:user
Совпадения: /movies/abc
, /movies/123
, /movies/abc123
basicaly express будет соответствовать чему-либо после /movies/
и присвоит значение req.params.user
.
Но если вы хотите вернуть фильмы, которые может увидеть зарегистрированный пользователь, возможно, URL должен быть:
/movies/logged-user
ТОЛЬКО соответствует этому точному URL. Здесь нет параметров маршрута, logged-user
является текстом c и является частью URL.
Можно утверждать, что logged-user
не является необходимым. Возможно, правильный URL должен быть:
/movies
Разница между /movies/logged-user
и /movies
является чисто семантической. Первый говорит явному человеку, который будет использовать api url, что фильмы, которые будут перечислены в списке, - это те, которые могут видеть зарегистрированные пользователи. Второй говорит, что будут перечислены фильмы, но не будет указано ничего другого, возможно, вводит в заблуждение идею, в которой будут перечислены все фильмы.