skip to Main Content

I am attempting to send FormData from my React-Native application to my Express (everything in typescript) backend. However, nothing I have attempted has seemed to work.

Client Side:

const handlePickImage = async () => {
    try {
      const result = await ImagePicker.launchImageLibraryAsync({
        mediaTypes: ImagePicker.MediaTypeOptions.Images,
        allowsEditing: true,
        aspect: [1, 1],
        quality: 1,
      });
  
      if (!result.canceled) {
        const uri = result.assets[0].uri;
        setProfileImage(uri);
  
        const formData = new FormData();
  
        const fileName = uri.split('/').pop();
  
        const response = await fetch(uri);
        const blob = await response.blob();
        
        formData.append('profileImage', blob, fileName || 'profile_image.jpg');
        await updateProfilePicture(formData, user.uid);
      }
    } catch (error) {
      console.error('Error picking image:', error);
    }
  };

Frontend API:

export const updateProfilePicture = async (profilePicture: FormData, userId: string) => {
    try {
      console.log("Profile picture: ", profilePicture)
      const response = await fetch(`${API_URL}/user/updateprofilepicture/${userId}`, {
        method: 'POST',
        headers: {
          Accept: 'application/json',
        },
        body: profilePicture,
      });
  
      if (!response.ok) {
        throw new Error('Failed to update profile picture');
      }
  
      const data = await response.json();
      console.log('Profile image uploaded successfully:', data);
    } catch (error) {
      console.error('Error updating profile picture:', error);
    }
  };

Backend Route:

const multer = require('multer');
const express = require('express');


const router = express.Router();

const storage = multer.memoryStorage();
const upload = multer({ storage: storage });

router.post('/updateprofilepicture/:userId', upload.single('profileImage'), updateProfilePicture);

Controller:

import { Multer } from 'multer';


export const updateProfilePicture = async (req: Request, res: Response) => {
  try {
    const userId = req.params.userId;

    const file = req.file;

    if (!file) {
      return res.status(400).json({ error: 'No file uploaded' });
    }

    const imageUrl = await uploadProfileImage(userId, file);

    res.status(200).json({ imageUrl });
  } catch (error) {
    console.error('Error in updateProfilePicture controller:', error);
    res.status(500).json({ error: 'Error uploading profile picture' });
  }
};

Am I missing something simple? I am able to log the data in the frontend api without issue, but I am unable to send the data to the controller and pick up anything.

Thank you

2

Answers


  1. Chosen as BEST ANSWER

    I got this working doing two seemingly innocuous things:

    1. I removed all headers from the frontend api request.
    2. I changed my import from import { Multer } from 'multer'; to import multer from 'multer';

    All of the sudden the backend controller breakpoint was hit successfully and I was able to go from there.


  2. I’ve had this experience several times, and a few of those times, what worked was to update the header. can you try using multipart/form-data like this

    export const updateProfilePicture = async (profilePicture: FormData, userId: string) => {
        try {
          console.log("Profile picture: ", profilePicture)
          const response = await fetch(`${API_URL}/user/updateprofilepicture/${userId}`, {
            method: 'POST',
            headers: {
                'Content-Type': 'multipart/form-data',
            },
            body: profilePicture,
          });
      
          if (!response.ok) {
            throw new Error('Failed to update profile picture');
          }
      
          const data = await response.json();
          console.log('Profile image uploaded successfully:', data);
        } catch (error) {
          console.error('Error updating profile picture:', error);
        }
      };
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search