Mongoose分页报Cast to ObjectId failed for value "num"错误
核心报错Cast to ObjectId failed for value "num" (type string) at path "_id" for model "Return"、后端/num接口内console无输出的直接原因是后端路由匹配顺序错误:returnRouter.js中定义的带:id参数的动态路由位置在/num静态路由之前,Express会按从上到下的顺序匹配路由,请求/api/returns/num时会被提前匹配到动态/:id路由,把字符串"num"作为_id参数传入查询逻辑,触发MongoDB的ObjectId类型转换错误,写在后面的/num接口逻辑永远不会被执行,自然不会有console输出。
除此之外代码中还存在3处会导致功能异常的问题,逐一修复即可。
1. 调整后端路由顺序
打开returnRouter.js,将所有静态路径路由(比如/num)移动到所有带路径参数的动态路由(比如/:id、/:id/delete这类路由)的最前面。
Express路由匹配规则为从上到下顺序匹配,只要命中符合规则的路由就会终止匹配流程,动态路由
/:id可以匹配所有/任意字符串格式的路径,放在静态路由前会拦截所有对应请求。
参考正确写法调整/num接口:
// 静态路由放最前面 returnRouter.get( '/num', isAuth, expressAsyncHandler(async (req, res) => { const perPage = 20 const total = await Return.countDocuments(); console.log(total) const totalPages = Math.ceil(total / perPage); console.log(totalPages) // 建议返回对象格式,后续扩展字段更方便,不需要额外调整前端取值逻辑 res.status(200).send({ totalPages }); }), ); // 所有动态参数路由放在静态路由之后 returnRouter.get('/:id', /* 对应逻辑 */)
调整后重启后端服务,再请求/api/returns/num即可看到console打印内容,ObjectId转换报错会直接消失。
2. 修复前端导入语法错误
打开ReturnListScreen.js,第3行的导入语句缺少分隔逗号,会直接导致前端编译失败:
原错误代码:
import {listReturns returnPagesActions } from '../actions/returnActions';
修改为:
import { listReturns, returnPagesActions } from '../actions/returnActions';
3. 修复Reducer初始值类型错误
打开returnReducer.js,totalPages为数字类型,初始值设置为空数组会导致分页组件拿到错误类型无法正常渲染:
原错误代码:
export const returnPagesReducer = (state = {totalPages:[]}, action) => {
修改为:
export const returnPagesReducer = (state = {totalPages: 0}, action) => {
如果后端调整为返回{totalPages: 数字}的格式,现有success逻辑无需改动;如果后端保持直接返回数字/数字字符串的写法,需要在success赋值时做类型转换,避免传入字符串导致分页计算错误:
case RETURN_PAGE_SUCCESS: return { ...state, loading: false, totalPages: Number(action.payload)};
4. 校验基础配置
- 检查
returnConstants.js中分页相关的三个Action Type是否正确定义,没有和其他模块的Action Type重名:export const RETURN_PAGE_REQUEST = 'RETURN_PAGE_REQUEST' export const RETURN_PAGE_SUCCESS = 'RETURN_PAGE_SUCCESS' export const RETURN_PAGE_FAIL = 'RETURN_PAGE_FAIL' - 检查
store.js中是否正确注册returnPagesReducer,确保挂载的state键名为returnPages,和页面中useSelector((state) => state.returnPages)的取值路径对应。
- 重启后端服务后直接请求
/api/returns/num接口,确认可以正常返回总页数,后端控制台有对应打印,不再出现ObjectId转换报错 - 前端修复语法错误后刷新页面,通过Redux调试工具检查
RETURN_PAGE_SUCCESS动作的payload是否正确,store中returnPages.totalPages为正确的数字值 - 切换分页按钮,确认
listReturns接口携带正确的page参数,列表数据、分页组件状态联动正常
内容的提问来源于stack exchange,提问作者pelotador.1

