skip to Main Content

I am trying to make this feature when user can upload both CV and his image.

However whenever I try to send both at the same time to backend I get bad Request error 400. I tried to change things but I just cant seem to figure that out why it goes to 400 , when I upload image , or cv while commenting out first one , or the latter one , and when done separately it works fine.

here is my backend code:

  @Post('signup')
  @UseInterceptors(FileInterceptor('cv'), FileInterceptor('avatarImage'))
  async signUp(
    @Body() signupDto: SignupDto,
    @UploadedFile() cv: Express.Multer.File,
    @UploadedFile() avatarImage: Express.Multer.File,
  ): Promise<any> {
    if (!cv) {
      throw new Error('CV file is required.');
    }
    signupDto.cvFileName = cv.originalname;
    signupDto.cvFileBuffer = cv.buffer;

    signupDto.cv = await this.fileUploadService.uploadFileCv(
      signupDto.cvFileName,
      signupDto.cvFileBuffer,
    );

    if (!avatarImage) {
      throw new Error('Avatar Image is required');
    }

    signupDto.avatarImageName = avatarImage.originalname;
    signupDto.avatarImageFileBuffer = avatarImage.buffer;

    signupDto.avatarImage = await this.fileUploadService.uploadImage(
      signupDto.avatarImageName,
      signupDto.avatarImageFileBuffer,
    );
    
    return this.userService.createUser(signupDto);
}

I can send them separately , but I cant send them at the same time.
in addition I provide snippet of fetching logic.

  const handleRegistration = async (event: FormEvent<HTMLFormElement>) => {
    event.preventDefault();

    const formData = new FormData();
    if (selectedCvFile.length > 0) {
      formData.append("cv", selectedCvFile[0] || "");
    }
    if (selectedImagesForAvatar.length > 0) {
      formData.append("avatarImage", selectedImagesForAvatar[0] || "");
    }
 
    formData.append("username", formState.username || "");
    formData.append("firstName", formState.firstName || "");
    formData.append("lastName", formState.lastName || "");
    formData.append("password", formState.password || "");
    formData.append("email", formState.email || "");
    formData.append("phoneNumber", formState.phoneNumber || "");
    formData.append("address", formState.address || "");
    formData.append("city", formState.city || "");
    formData.append("role", formState.role || ""); 
    dispatch({ type: "CLEAR_ALERTS" });
    try {
      const response = await fetch("http://localhost:3000/auth/signup", {
        method: "POST",
        body: formData,
      });

      const data = await response.json();

      if (response.ok) {
        dispatch({
          type: "SHOW_SUCCESS",
          payload: `You have registered correctly !`,
        });
        console.log(data);
        localStorage.setItem("token", data.accessToken);

      } else {
        dispatch({ type: "SHOW_ERROR", payload: response.statusText });
        console.error("Registration failed:", response.statusText, response);
        // Handle failed registration, e.g., show an error message
      }
    } catch (error) {
      console.error("Error during registration:", error);
      // Handle any other errors that may occur during registration
    }
  };

If you have idea what I can do to make it work , please do so : )

Thanks

2

Answers


  1. Chosen as BEST ANSWER
    @Post('signup')
      @UseInterceptors(
        FileFieldsInterceptor([
          { name: 'cv', maxCount: 1 },
          { name: 'avatarImage', maxCount: 1 },
        ]),
      )
      async signUp(
        @Body() signupDto: SignupDto,
        @UploadedFiles()
        files: { cv?: Express.Multer.File; avatarImage?: Express.Multer.File },
      ): Promise<any> {
        const cv = files.cv[0];
        const avatarImage = files.avatarImage[0];
    
        console.log(cv, avatarImage);
    

    I just implemented solution from offical docs , and it worked.

    The main take from this problem is... Read documentation : )


  2. Not answering your exact problem, but why not just make two separate calls to this.fileUploadService.uploadFileCv ? You could promise.all wrap it and just get both results from the data it returns.

    Especially if youre using something like mongo this could actually even be preferred.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search