You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

表单提交时req.params无法传递至控制器的问题求助

电影清单程序提交电影报错问题

我开发了一个电影清单程序,提交电影时出现以下错误,已经自行测试并搜索过类似问题,但没有完全匹配的结果,希望只是一个没发现的简单疏漏。

Cannot read property 'listTitle' of null
TypeError: Cannot read property 'listTitle' of null at module.exports.addMovie (/Users/---/Documents/movieInventoryApp/controllers/movies.js:73:22) at processTicksAndRejections (internal/process/task_queues.js:95:5)

参数列表到达控制器时为空,已验证以下内容:

  • 路由器处list ID为undefined(通过测试打印中间件确认)
  • 请求能进入控制器,但list._id及其他参数都没传递过来
  • 反复检查拼写,逐行对比功能正常的同类文件,优化过变量命名
  • 中间件验证器未抛出错误,移除验证器测试后问题依旧

清单show.ejs(提交表单部分)

<div class="col-6">
        <% if(currentUser) { %>
        <h2>Add a Movie</h2>
        <form class="mb-3 needs-validation" action="/lists/<%= list._id %>/movies" method="POST" novalidate>
          <% console.log(list._id) //打印测试:输出正确的id%>
          <div class="mb-3">
            <label for="movieTitle">Movie Title</label>
            <input type="text" name="movie[movieTitle]" id="movieTitle">
          </div>
          <div class="mb-3">
            <label for="movieDescription">Description</label>
            <input type="text" name="movie[movieDescription]" id="movieDescription" required>
          </div>
          <button class="btn btn-success">Add Movie</button>
        </form>
        <% } %>
      </div>
    </div> 

app.js(路由配置部分)

app.use('/lists', listRoutes);
app.use('/lists/:id/movies', movieRoutes); //路由看似正常
app.use('/', userRoutes);

movies.js 路由器

const express = require('express');
const router = express.Router();
const movies = require('../controllers/movies');
const catchAsync = require('../utils/catchAsync');
//const Movie = require('../models/movie');
const { isLoggedIn, validateMovie, isAuthor, testPrint } = require('../middleware');

// 移除了注释代码

router.post('/', isLoggedIn, validateMovie, /*testPrint,*/ catchAsync(movies.addMovie)); //打印测试:参数没从路由器传过来

router.delete('/:movieId', isLoggedIn, isAuthor, catchAsync(movies.deleteMovie));

module.exports = router;

movies.js 控制器

const Movie = require('../models/movie');
const List = require('../models/list');

// 移除了注释代码

module.exports.addMovie = async (req, res) => {
    console.log( req.params ) ;//////打印测试:params为空
    const { id } = req.params;
    console.log(id);///////打印测试:undefined
    const list = await List.findById(req.params.id);
    console.log(list.listTitle);////////打印测试:undefined
    const movie = new Movie(req.body.movie);
    console.log(movie.movieTitle);////////打印测试:undefined
    movie.movieAuthor = req.user._id;
    list.listOfMovies.push(movie);
    await movie.save();
    await list.save();
    req.flash('success', 'New review added!');
    res.redirect(`/lists/${list._id}`);
}

module.exports.deleteMovie = async (req, res) => {
    const { id, movieId } = req.params;
    await List.findByIdAndUpdate(id, { $pull: { movieList: movieId } });
    await Movie.findByIdAndDelete(MovieId);
    req.flash('success', 'Successfully deleted movie')
    res.redirect(`/lists/${id}`);
}

清单路由器

const express = require('express');
const router = express.Router();
const lists = require('../controllers/lists');
const catchAsync = require('../utils/catchAsync');
const { isLoggedIn } = require('../middleware');

router.route('/')
    .get(catchAsync(lists.index))
    .post(catchAsync(lists.createList))

router.get('/new', isLoggedIn, lists.renderNewForm);

router.route('/:id')
    .get(catchAsync(lists.showList))
    .put(catchAsync(lists.updateList))
    .delete((lists.deleteList))

router.get('/:id/edit', catchAsync(lists.renderEditForm));

module.exports = router;

清单控制器

const { register } = require('../models/list');
const List = require('../models/list');
//const Movie = require('../models/movie');

module.exports.index = async (req, res) => {
    const unsortedLists = await List.find({});
    const lists = unsortedLists.sort((a,b) => {
        if (a.listTitle < b.listTitle) {
            return -1;
        }
        if (a.listTitle > b.listTitle) {
            return 1;
        }
        return 0;
    });
    res.render('lists/index', { lists })
}

module.exports.renderNewForm = (req, res) => {
    res.render('lists/new');
}

module.exports.createList = async (req, res, next) => {
    const list = new List(req.body.list);
    list.listAuthor = req.user._id;
    //const movie = new Movie({title: 'title', description: 'description'});
    //list.movies.push(movie);
    await list.save();
    req.flash('success', 'Successfully made a new list!');
    res.redirect(`/lists/${list._id}`)
}

// 移除了注释代码

module.exports.showList = async (req, res,) => {
    const list = await List.findById(req.params.id).populate({ path:'listOfMovies' }).populate('listAuthor');
    if (!list) {
        req.flash('error', 'Cannot find that list!');
        return res.redirect('/lists');
    }
    res.render('lists/show', { list });
}

module.exports.renderEditForm = async (req, res) => {
    const { id } = req.params;
    const list = await List.findById(id)
    if (!list) {
        req.flash('error', 'Cannot find that list!');
        return res.redirect('/lists');
    }
    res.render('lists/edit', { list });
}

module.exports.updateList = async (req, res) => {
    const { id } = req.params;
    const movie = await List.findByIdAndUpdate(id, { ...req.body.list });
    req.flash('success', 'Successfully updated list!');
    res.redirect(`/lists/${list._id}`)
}

module.exports.deleteList = async (req, res) => {
    const { id } = req.params;
    await List.findByIdAndDelete(id);
    req.flash('success', 'Successfully deleted list')
    res.redirect('/lists');
}

内容的提问来源于stack exchange,提问作者Audra W.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 03:10:36