Node.js保存todoModel至data.json时title、description字段丢失问题
问题根因
todo.model.js模块加载时就固定读取data.json根下的title、description,而你实际存储的data.json是数组结构,数组本身没有title、description属性,读取到的值本身就是undefined,JSON序列化时会自动丢弃值为undefined的字段。- 你把
todoModel做成了固定导出的单例对象,不是每次新增todo时动态生成的,所有新增操作都共用模块加载时生成的同一个对象,根本拿不到每次POST请求传的新数据。 todo.controller.js中接收到请求的body数据后完全没有解析、也没有传递给todo生成逻辑,直接push了提前生成的旧todoModel。
修复方案
1. 修改 todo.model.js
改造成工厂函数,接收外部传入的标题、描述参数,动态生成新的todo对象,不要在模型层读取本地文件:
const { v4: uuidv4 } = require("uuid"); module.exports = (title, description) => ({ id: uuidv4(), title, description, dateOfCreate: new Date(), lastModified: new Date(), check: false });
2. 修改 todo.controller.js
补全请求body解析、现有数据读取、新todo生成的逻辑,修正错误的异常处理:
const fs = require("fs").promises; const path = require("path"); const createTodoModel = require("../models/todo.model"); class todoController { async createTodo(req, res) { let bodyBuffer = []; req.on("data", chunk => { bodyBuffer.push(chunk); }).on("end", async () => { try { // 解析请求体数据 const reqBody = JSON.parse(Buffer.concat(bodyBuffer).toString()); const { title, description } = reqBody; if (!title || !description) { res.writeHead(400, { "Content-Type": "application/json" }); return res.end(JSON.stringify({ error: "title和description为必填字段" })); } // 读取已有todo列表 const dataFilePath = path.join(__dirname, "../data/data.json"); const fileContent = await fs.readFile(dataFilePath, "utf-8"); const todos = JSON.parse(fileContent); // 生成新todo并写入文件 const newTodo = createTodoModel(title, description); todos.push(newTodo); await fs.writeFile(dataFilePath, JSON.stringify(todos, null, 2)); // 返回成功响应 res.writeHead(201, { "Content-Type": "application/json" }); res.end(JSON.stringify(newTodo)); } catch (err) { res.writeHead(500, { "Content-Type": "application/json" }); res.end(JSON.stringify({ error: err.message })); } }); } } module.exports = new todoController();
调用说明
发起POST请求时需要携带请求头 Content-Type: application/json,请求体格式示例:
{ "title": "示例待办标题", "description": "示例待办描述内容" }
内容的提问来源于stack exchange,提问作者tan4ok
相关产品推荐
相关产品推荐

