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

解决mongoose中addTask方法报concat未定义的TypeError

解决Mongoose实例方法中this.tasks undefined的问题

用户通过Mongoose定义包含tasks数组的userSchema,尝试用实例方法addTask向tasks添加数据时,报错TypeError: Cannot read properties of undefined (reading 'concat'),相关代码如下:

userSchema代码

const mongoose = require("mongoose");

const userSchema = new mongoose.Schema({
    name:{
        type: String,
        required: true
    },
    email:{
        type: String,
        required: true
    },
    password:{
        type: String,
        required: true
    },
    tasks:[ {
        title: {
            type: String,
        },
        description: {
            type: String,
        },
        date: {
            type: Date,
            default: Date.now
        },
        author: {
            type: String,
        },
        isDone: {
            type: Boolean
        },
        isFail: {
            type: Boolean
        }
    }]
})

// creating task
userSchema.methods.addTask = async(title, description, author)=>{
    try {
        this.tasks = this.tasks.concat({title, description, author});
        await this.save();
        return this.tasks;
        
    } catch (error) {
        console.log(error);
    }
    
}

const User = mongoose.model("User", userSchema);
module.exports = User;

POST方法代码

router.post("/createtask", async(req, res)=>{
    try {
        const {title, description, author} = req.body;
        console.log("creating a new task");
        if(!title){
            return res.json({error: "plz fill title"});
        }
        const userfound = await User.findOne({email: req.body.email});
        console.log(userfound);
        if(userfound){
            const userTask = await userfound.addTask(title, description, author);
            await userfound.save();
            res.status(201).json({message: "successfully created a task."});
        }
    } catch (error) {
        console.log(error);
    }
})

错误原因

  1. 箭头函数导致this指向错误:实例方法使用箭头函数时,this不会绑定到Mongoose的User文档实例,而是继承外层作用域的上下文,因此this.tasks为undefined,调用concat时触发报错。
  2. 重复执行save操作:POST方法中调用userfound.addTask后又执行userfound.save(),但addTask内部已经完成了保存,属于冗余操作。

解决方案

1. 修改实例方法为普通函数

将addTask的箭头函数改为普通函数,让this正确绑定到当前文档实例,同时增加数组初始化判断:

userSchema.methods.addTask = async function(title, description, author) {
    try {
        // 确保tasks数组存在,避免未初始化的情况
        this.tasks = this.tasks || [];
        this.tasks = this.tasks.concat({title, description, author});
        await this.save();
        return this.tasks;
    } catch (error) {
        console.log(error);
    }
}

2. 优化POST方法,移除重复save

router.post("/createtask", async(req, res)=>{
    try {
        const {title, description, author, email} = req.body;
        console.log("creating a new task");
        if(!title){
            return res.json({error: "plz fill title"});
        }
        const userfound = await User.findOne({email});
        console.log(userfound);
        if(userfound){
            await userfound.addTask(title, description, author);
            res.status(201).json({message: "successfully created a task."});
        } else {
            res.status(404).json({error: "User not found"});
        }
    } catch (error) {
        console.log(error);
        res.status(500).json({error: "Server error"});
    }
})

3. 可选:Schema层面设置tasks默认空数组

从根源避免tasks为undefined的情况:

tasks: {
    type: [{
        title: { type: String },
        description: { type: String },
        date: { type: Date, default: Date.now },
        author: { type: String },
        isDone: { type: Boolean },
        isFail: { type: Boolean }
    }],
    default: []
}

内容的提问来源于stack exchange,提问作者Jatin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 08:07:50