Home > Enterprise >  Unable to save nested data in mongodb using NestJs mongoose
Unable to save nested data in mongodb using NestJs mongoose

Time:02-20

I am creating application where I amusing NestJs framework and using mongodb database with mongoose ORM I have nested data structure that I am trying to save inside database but its throwing error when I am saving it. Below is my error:

[Nest] 11196  - 19/02/2022, 6:01:30 pm   ERROR [ExceptionsHandler] Cannot set property 'city' of undefined
TypeError: Cannot set property 'city' of undefined
at UserService.addUser (D:\nest\nested-schema-proj\src\user\user.service.ts:18:27)
at UserController.addUser (D:\nest\nested-schema-proj\src\user\user.controller.ts:11:33)

Below is postman request:

enter image description here

When I am posting data as raw JSON that can be seen in screenshot below then it is added successfully.Then why it not adding using first way

enter image description here

Below is my code:

user.schema.ts

import mongoose from "mongoose";

const addressSchema = new mongoose.Schema({
  city:{type:String},
  state:{type:String}
});

export const UserSchema = new mongoose.Schema({

 name:{type:String},
 age:{type:Number},
 address:addressSchema

});


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

export interface AllUser{
 name:string;
 age:number;
 address:Address;
}

user.dto.ts

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

class Address{
  city:string;
  state:string;
}

user.controller.ts

import { Body, Controller, Post } from '@nestjs/common';
import { UserDto } from './dto/user.dto';
import { UserService } from './user.service';

@Controller()
export class UserController {
constructor(private userService:UserService){}

@Post('addUser')
addUser(@Body() userDto:UserDto){
    return this.userService.addUser(userDto);
  }
}

user.service.ts

import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model} from 'mongoose';
import { UserDto } from './dto/user.dto';
import { AllUser } from './schema/user.schema';

@Injectable()
export class UserService {
constructor(@InjectModel('AllUser') private readonly userModel:Model<AllUser>){}

async addUser(userDto:UserDto): Promise<AllUser>{

    console.log(userDto);

     const data = new this.userModel();
     data.name = userDto.name;
     data.age = userDto.age;
     data.address.city = userDto.address.city; //Showing error in this line
     data.address.state = userDto.address.state;

     const result = await data.save();
     return result;

     //Posting data as a raw JSON as shown in 2nd screenshot
     // const data = new this.userModel(userDto);
     // const result = await data.save();
     // return result;  
   }
 }

Someone let me know what I am doing wrong.Any help would be appreciated.

CodePudding user response:

You cannot save because the user model is interface object which is injected on initialisation of your service. Also you cannot this model by initiating and access its property.

Instead you can expand the DTO and save it. Also you can manipulate you extra fields if you want from your code. In below example I have added date/time of document creation

 return await new this.userModel({
          ...userDto,
          created_at: moment.utc() //Manipulate your extra fields and set here
        }).save();

Also you can set you own DTO object if you need to again maipulate data on controller level and pass that DTO direclty to service and just save it

For example:

//In Controller
 const data = new UserDto();
 data.name = userDto.name;
 data.age = userDto.age;
 data.address.city = userDto.address.city; 
 data.address.state = userDto.address.state;
 data.created_at: new Date();
return await this.userService.addUser(data);

//Service:
async addUser(userDto:UserDto): Promise<AllUser>{

console.log(userDto);

 return await new this.userModel({
      ...userDto,
      created_at: moment.utc() //Manipulate your extra fields and set here
    }).save();
}
 
  • Related