Почему req.params.filmId или в более общем смысле req.params.name неразрешенная переменная?

#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" , как бы вы узнали a filmId для фильма, который не был создан, как бы это вызывалось через 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