2

I am creating application where I am using NestJs framework and using MongoDB database with Mongoose ORM. I have nested data structure that I am trying to save inside database, but it's 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 my 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;  
   }
 }

What am I doing wrong?

3
  • Are you able to xee date when you print console.log(userDto); Commented Feb 19, 2022 at 14:00
  • Yeah its visible in console Commented Feb 19, 2022 at 14:08
  • I have updated user.service.ts file in post take a look i tried data adding using raw JSON format and it got added but Why its not adding using first way. Commented Feb 19, 2022 at 14:09

2 Answers 2

1

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();
}
 
Sign up to request clarification or add additional context in comments.

5 Comments

I am trying your solution but its throwing the same error TypeError: Cannot set property 'city' of undefined.
if i am saving data like return await new this.userModel(userDto).save() and posting body in raw JSON then its saving but when I am using your solution and posting using raw JSON then its showing same TypeError.
I updated answer to pass data object instead of DTO from controller Check that now. Also added await in controller call to service
Still same error
I think you need to send the JSON raw format, nested form data from POSTman is tricky ,
0

use Address.city in postman, will definitely work

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.