使用node-restful调用Model.methods报Cannot convert undefined or null to object错误如何解决
问题根因
该错误由node-restful库的兼容问题导致:该库已停止维护(最后一次更新为2017年),没有适配mongoose的discriminator继承机制。你通过Sensor.discriminator()生成的measureSensor是mongoose子模型实例,没有被node-restful正确初始化内部必需的routes属性,调用.methods()方法时库内部尝试访问undefined的routes对象就触发了报错。
可落地解决方案
方案1:修正restful模型导出逻辑(适配现有写法)
你当前的measureSensor.js没有把discriminator生成的模型实例传递给restful.model,导致node-restful没有正确初始化内部属性,修改measureSensor.js的导出逻辑即可:
const { Schema } = require('mongoose') const restful = require('node-restful') const mongoose = restful.mongoose const Sensor = require('../sensor') const measureSensor = Sensor.discriminator('MeasureSensor', new mongoose.Schema({ measurerType: { type: String, required: false, uppercase: true, enumValues: ['HEAT', 'RUID'] } })) // 把discriminator生成的模型实例作为第二个参数传给restful.model module.exports = restful.model('MeasureSensor', measureSensor)
修改后重新启动项目,大部分情况下该报错会直接消失。
方案2:弃用node-restful,手写简易CRUD路由(推荐长期使用)
如果方案1无效,建议直接替换不再维护的node-restful,手写路由逻辑复杂度很低,且完全兼容mongoose所有特性,measureSensorService.js示例写法如下:
const express = require('express') const router = express.Router() const MeasureSensor = require('./measureSensor') // 查询所有 router.get('/', async (req, res) => { try { const data = await MeasureSensor.find(req.query) res.json(data) } catch (err) { res.status(500).json({error: err.message}) } }) // 新增 router.post('/', async (req, res) => { try { const data = await MeasureSensor.create(req.body) res.status(201).json(data) } catch (err) { res.status(400).json({error: err.message}) } }) // 更新 router.put('/:id', async (req, res) => { try { const data = await MeasureSensor.findByIdAndUpdate(req.params.id, req.body, {new: true, runValidators: true}) res.json(data) } catch (err) { res.status(400).json({error: err.message}) } }) // 删除 router.delete('/:id', async (req, res) => { try { await MeasureSensor.findByIdAndDelete(req.params.id) res.json({success: true}) } catch (err) { res.status(500).json({error: err.message}) } }) module.exports = { register: (parentRouter, prefix) => { parentRouter.use(prefix, router) } }
该写法完全兼容你现有routes.js里的.register()调用逻辑,无需修改其他代码。
方案3:放弃使用discriminator(临时应急)
如果一定要保留node-restful,可以把MeasureSensor的字段直接合并到父级Sensor模型中,增加type字段区分传感器类型,避免使用discriminator继承即可兼容node-restful的逻辑。
内容的提问来源于stack exchange,提问作者liegolas
相关产品推荐
相关产品推荐

