Search code examples
node.jsnestjsmultipartform-data

In Nest.Js How to send body with form data request and apply body request validation. File is optional to be attached


In Nest.js, when i want to send a request with form data that may or may not include a file attachment then i am not able to get both body request and file at same request and also validate the body request that fields are valid or not.

import {
  Body,
  Controller,
  MaxFileSizeValidator,
  ParseFilePipe,
  Post,
  UploadedFile,
  UseInterceptors,
} from "@nestjs/common";
import { JoiValidationPipe } from "../../pipes/validation/joi-validation.pipe";
import { UserValidatorSchema } from "./validator/account-register.validator";
import { CreateUserDto } from "./dtos/account-register.dto";
import { AccountRegisterService } from "./account-register.service";
import { FileInterceptor } from "@nestjs/platform-express";
import { MAX_FILE_SIZE } from "../../constants/multer.constants";

@Controller("user")
export class FormdataWithFileController {
  constructor(private readonly _formdataWithFileService: formdataWithFileService) {}

  @Post("formdataWithFile")
  @UseInterceptors(FileInterceptor("file"))
  private async Signup(
    @UploadedFile(
      new ParseFilePipe({
        validators: [
          new MaxFileSizeValidator({ maxSize: MAX_FILE_SIZE })
        ],
      })
    )
    file,
  ) {
    return await this._formdataWithFileService.execute(file);
  }
}

Solution

  • fileIsRequired: false is put in the @UploadedFile() Pipe to make file optional.

    @Body(new JoiValidationPipe<CreateUserDto>(UserValidatorSchema)) : body CreateUserDto) decorator will perform body validation.

    import {
      Body,
      Controller,
      MaxFileSizeValidator,
      ParseFilePipe,
      Post,
      UploadedFile,
      UseInterceptors,
    } from "@nestjs/common";
    import { JoiValidationPipe } from "../../pipes/validation/joi-validation.pipe";
    import { UserValidatorSchema } from "./validator/account-register.validator";
    import { CreateUserDto } from "./dtos/account-register.dto";
    import { AccountRegisterService } from "./account-register.service";
    import { FileInterceptor } from "@nestjs/platform-express";
    import { MAX_FILE_SIZE } from "../../constants/multer.constants";
    
    @Controller("user")
    export class FormdataWithFileController {
      //
      constructor(private _formdataWithFileService: FormdataWithFileService) {}
    
      @Post("formdataWithFile")
      @UseInterceptors(FileInterceptor("file"))
      private async Signup(
        @UploadedFile(
          new ParseFilePipe({
            validators: [
              new MaxFileSizeValidator({ maxSize: MAX_FILE_SIZE }),
              // new FileTypeValidator({ fileType: "image/jpeg" }),
            ],
            fileIsRequired: false,
          })
        )
        file,
        @Body(new JoiValidationPipe<CreateUserDto>(UserValidatorSchema)) body: CreateUserDto
      ) {
        // acccess file & body data
        const fileWithBody = {
          body,
          file
        };
        return await this._formdataWithFileService.execute(fileWithBody)
      }
    }