#javascript #node.js #mongodb #express #schema
#javascript #node.js #mongodb #выразить #схема
Вопрос:
У меня возникла проблема с req.params. Я знаю о разнице между req.body и req.params, в частности, что req.params предназначен для параметров маршрута. В моем коде ниже (фрагмент A) параметром, к которому я хотел бы получить доступ, является значение :filmId . Однако я получаю сообщение о неразрешенной переменной, и оно не работает для меня, я не могу получить доступ к параметру filmId.
Из всего, что я могу сказать, я правильно использую req.params.filmId, но, возможно, это связано с тем, где я помещаю код в два разных блока router.post, которые у меня есть, у меня есть router.post к корневому пути / в моем films.js (фрагмент B) файл маршрута, но ятакже есть router.post по пути /:filmId . Смотрите (фрагмент C.1 и C.2) для параметров to different router.post, у меня возникает проблема, когда я использую блок кода в любом месте. Должны ли router.post и router.get располагаться в определенном порядке? Заранее спасибо за помощь.
Фрагмент A.1
router.get("/", function(req, res, next) {
Film.find()
.exec()
.then(docs => {
console.log(docs);
res.status(200).json(docs);
})
.catch(err => {
console.log(err);
res.status(500).json({error: err});
});
});
Фрагмент A.2
router.get("/:filmId", function(req, res, next) {
const id = req.params.filmId;
Film.findById(id)
.exec()
.then(doc => {
console.log(doc);
res.status(200).json(doc);
})
.catch(err => {
console.log(err);
res.status(500).json({error: err});
});
});
Фрагмент B
Это мой film.js модель
const mongoose = require("mongoose");
const filmSchema = new mongoose.Schema({
_id : mongoose.Schema.Types.ObjectId,
filmTitle: {type: String, required: true},
filmRating: {type: Number, required: true}
});
module.exports = mongoose.model("Film", filmSchema);
Фрагмент C.1
router.post("/", function (req,res,next){
const film = new Film({
_id: new mongoose.Types.ObjectId(),
filmTitle: req.body.filmTitle,
filmRating: req.body.filmRating
});
film
.save()
.then(result => {
console.log(result);
res.status(201).json({
message: "Handling POST requests to /films",
film: film
});
})
.catch(err => {
console.log(err);
res.status(500).json({
error: err
});
});
});
Фрагмент C.2
router.post("/:filmId", function (req,res,next){
const film = new Film({
_id: new mongoose.Types.ObjectId(),
filmTitle: req.body.filmTitle,
filmRating: req.body.filmRating
});
film
.save()
.then(result => {
console.log(result);
res.status(201).json({
message: "Handling POST requests to /films",
film: film
});
})
.catch(err => {
console.log(err);
res.status(500).json({
error: err
});
});
});
Комментарии:
1. Как вы вызываете
POST
конечную точку? Кроме того, вам не нужно указывать_id : mongoose.Schema.Types.ObjectId,
для вашей схемы и не делать_id: new mongoose.Types.ObjectId(),
этого вPOST
обработчике, mongoose_id
автоматически добавляет для вас как для вашей модели, так и при созданииFilm
. Кроме того, вам, вероятно, следует делать это толькоres.json
дляthen()/catch()
того, чтобы убедиться, что вы отправляете ответ только после успешного или неудачного сохранения. Что касаетсяrouter.post("/:filmId"
, как бы вы узнали afilmId
для фильма, который не был создан, как бы это вызывалось через HTTP?2. Привет @AlexanderStaroselsky, спасибо за ответ, я изменил res.json, чтобы он был в then() / catch(), когда я вводил вопрос, но забыл переключить его в своем вопросе, я внес правку в исходное сообщение. Я новичок в программировании, что вы подразумеваете под конечной точкой POST? Значит, я не могу полностью удалить строки _id: из моей схемы и обработчика post? Я уже создавал фильмы с postman для добавления в базу данных, поэтому я подумал, что он сможет использовать те, которые уже созданы? Я не был точно уверен, как построить то, что я пытаюсь выполнить, как лучше всего с этим справиться?
3. Если вы не включите an
_id
при создании новойFilm
, когда вы успешноsave()
, вы увидите, что an_id
был создан / добавлен вfilm
. На базовом уровне вы можетеres.status(201).json(film)
внутриthen()
иres.status(someErrorCode).json(someErrorObject)
внутриcatch()
. Я имею вrouter.post("/:filmId"
виду, что это, вероятно, «неправильно», поскольку ваш клиент, вызывающий API, не знает идентификатор фильма, когда он вызывает сообщение, поскольку он просит создать совершенно новый фильм. Вероятноrouter.post("/",
, этого было бы достаточно.4. Для устранения неполадок я бы рекомендовал показать, как вы отправляете запрос
router.get('/:filmId'
GET от своего клиента.5. @AlexanderStaroselsky, хорошо, я понимаю автоматическую
_id
генерацию после успешного запускаsave()
, я понимаю, чтоrouter.post("/:filmId"
это логически не имеет смысла, поскольку я не могу отправлять сообщения в местоположение, которое еще не было сгенерировано!, когда я успешно использовал postman для их тестирования, я получал успешные запросы post для создания нового фильма с фрагментомC.1 илиrouter.post("/",
, я полагаю, я показал, как я делаю свойrouter.get('/:filmId'
запрос во фрагменте A.1 выше. Вам нужна дополнительная информация помимо этого? Я добавил свойrouter.get("/",
запрос как фрагмент A.2