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

使用NestJs与Mongoose在MongoDB中保存嵌套数据失败问题排查

解决NestJS + Mongoose中手动赋值嵌套Schema属性时的"Cannot set property 'city' of undefined"错误

这个问题的根源很直观:当你手动初始化this.userModel实例时,address属性默认是undefined,直接去给data.address.city赋值自然会触发"Cannot set property 'city' of undefined"的类型错误。而通过new this.userModel(userDto)直接传入完整DTO时,Mongoose会自动根据你定义的嵌套Schema为address创建对应的对象实例,所以不会出现这个问题。

下面给你几种可行的解决方案:

方案1:先初始化address对象再赋值属性

async addUser(userDto: UserDto): Promise<AllUser>{
    console.log(userDto);
    const data = new this.userModel();
    data.name = userDto.name;
    data.age = userDto.age;
    // 先给address初始化一个空对象
    data.address = {};
    data.address.city = userDto.address.city;
    data.address.state = userDto.address.state;
    const result = await data.save();
    return result;
}

方案2:直接赋值完整的address对象

这种方式更简洁,也符合Mongoose对嵌套Schema的处理逻辑:

async addUser(userDto: UserDto): Promise<AllUser>{
    console.log(userDto);
    const data = new this.userModel();
    data.name = userDto.name;
    data.age = userDto.age;
    // 直接把DTO中的address对象赋值给实例
    data.address = {
        city: userDto.address.city,
        state: userDto.address.state
    };
    const result = await data.save();
    return result;
}

方案3:使用Object.assign简化整体赋值

如果DTO的结构和Schema完全匹配,还可以用这种方式一步到位:

async addUser(userDto: UserDto): Promise<AllUser>{
    console.log(userDto);
    const data = new this.userModel();
    // 直接把DTO的所有属性赋值给实例
    Object.assign(data, userDto);
    const result = await data.save();
    return result;
}

额外小提示:修复DTO的类型定义问题

你的user.dto.ts中存在类型引用顺序问题:UserDto里先引用了Address类,但Address类定义在文件底部,这可能导致TS编译时的类型提示异常。建议调整为接口形式并提前声明:

export interface Address {
    city: string;
    state: string;
}

export class UserDto{
    name: string;
    age: number;
    address: Address;
}

内容的提问来源于stack exchange,提问作者Digvijay Singh Thakur

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 12:59:08