How we can use array of object in DTO with multipart-formdata in nestjs?

Viewed 4117

If I am using multipart-formdata and for DTO making use of field which includes an array of the object then formdata is not allowed to include that field in the swagger DTO. For now I have to go with raw JSON option from postman but I need the same implementation from nestjs inbuilt swagger DTO.

Please find below my controller code -

  @Post('/create')    
  @UseGuards(AuthGuard('jwt'))    
  @ApiBearerAuth()    
  @ApiOkResponse({})     
  @HttpCode(HttpStatus.OK)    
  @ApiOperation({ title: 'Create a project.' })   
  @ApiConsumes('multipart/form-data')   
  @UseInterceptors(FileInterceptor('file'))   
  @ApiImplicitFile({ name: 'image', required: true })   
  @ApiCreatedResponse({})    
    
  async create(@Req() request: Request, @UploadedFile() image: Express.Multer.File,) {    
    const jsonRequest = request.body;    
    if (request['user']) {   
      jsonRequest.createdBy = request['user']._id;    
      jsonRequest.updatedBy = request['user']._id;    
    }    
    const result = await this.projectsService.createProject(jsonRequest, image.buffer,  
   image.originalname, image.mimetype, image.size);    
    return result;   
  }    

Please find my swagger DTO

import { ApiModelProperty } from '@nestjs/swagger';    
import { IsString, MinLength, MaxLength, IsBoolean, IsArray } from 'class-validator';    
    
export class CreateProjectDto {    
  // template Id    
  @ApiModelProperty({    
    example: '604b3b7d45701c85711a9f5d',      
    description: 'The template Id of the project.',    
    format: 'string',     
    required: false    
  })    
  readonly templateId: string;    
    
  // organization Id     
  @ApiModelProperty({    
    example: '604f73e11f43762778292b81',     
    description: 'The organization Id of the project.',     
    format: 'string',     
  })    
  readonly organizationId: string;    
    
  // name     
  @IsString()   
  @MinLength(3)    
  @MaxLength(255)    
  @ApiModelProperty({   
    example: 'blender box',   
    description: 'The name of the project.',    
    format: 'string',   
  })   
  readonly name: string;

  // image    
  @ApiModelProperty({    
    example: 'default.png',    
    description: 'The image of the project.',    
    format: 'string',     
    required: false     
  })     
  readonly image: string;     
     
  // description    
  @IsString()    
  @ApiModelProperty({    
    example: 'test data',    
    description: 'The description of the project.',   
    format: 'string',    
    required: false      
  })    
  readonly description: string;    
    
  // Allow Participants to see responses   
  @IsString()    
  @ApiModelProperty({   
    example: "before/after",   
    description: 'Allow Participants to see responses from other participants.',    
    format: 'string',    
    required: false    
  })    
  readonly respondToQues: String;    
     
  // Add Participants Additional Fields    
  @IsArray()    
  @ApiModelProperty({    
    example: [     
      {    
      "fieldName": "Fav Color",   
      "fieldType": "checkbox",   
      "optionName": [    
        "option1",   
        "option2",   
        "option3",   
        "option4"    
      ]    
    },    
    {    
      "fieldName": "Meal Preference",    
      "fieldType": "radio button",    
      "optionName": [    
        "option1",   
        "option2",    
        "option3",    
        "option4"    
      ]    
    },    
    {   
      "fieldName": "Org Name",    
      "fieldType": "dropdown",   
      "optionName": [   
        "option1",   
        "option2",   
        "option3",   
        "option4"   
      ]   
    },   
    {    
      "fieldName": "Bio",    
      "fieldType": "single-line text",    
      "optionName": ""    
    },    
    {     
      "fieldName": "Tagline",    
      "fieldType": "multi-line text",    
      "optionName": ""   
    }    
  ],    
    description: 'Additional meta fields that can be attached to each participant within the project.',    
    format: 'string',    
    required: false   
  })    
  readonly additionalFields: string    
    
  // createdBy   
  createdBy: string;   
   
  // updatedBy    
  updatedBy: string;    
}    

Above DTO file having the Additional Fields option which is causing the issue in the above multipart-formdata.

3 Answers

When the property is an array, we must manually indicate the array type as shown below:

@ApiProperty({ type: [String] })
names: string[];

Either include the type as the first element of an array (as shown above) or set the isArray property to true.

//For an Object Input from swagger in nest js you can use the following syntax but for the input of array of object I am also searching the solution (8 _ 8)

@ApiProperty(
    {
        type: {
            name: { type: String, require: true },
            adress: { type: String, require: true },
            adress2: { type: String, require: true },
            adress3: { type: String, require: true },
            adress4: { type: String },
            adress5: { type: String },
            phone: { type: Number, require: true },
            phone2: { type: Number },
            city: { type: String, require: true },
            state: { type: String, require: true },
            postcode: { type: Number, require: true },
            country: { type: String, require: true },
            region: { type: String, require: true },
            fee: { type: Number },
            provider: { type: String },
        }
    }
)
shipping: {
    name: string,
    adress: string,
    adress2: string,
    adress3: string,
    adress4: string,
    adress5: string,
    phone: number,
    phone2: number,
    city: string,
    state: string,
    postcode: number,
    country: string,
    region: string,
    fee: number,
    provider: string,
}

Fortunately, I got the solution from gitHub to input object of array from swagger in nest js. Might be helpful for you so I shared code and link as well and tried it and worked fine for me too.

class ObjectDto {
      @ApiProperty()
      field: string;
    }

export class Params {
  @ApiProperty({
    isArray: true,
    type: ObjectDto,
  })
  arrayOfObjectsDto: ObjectDto[];
}
Related