laravelnext.jsaxiosswr

Multipart/form-data not working on axios put request


I am now trying to make a crud functionality with file upload on my project. I have done the creation part and it's all working fine since I implemented that with new FormData() by appending the file value and sending post request from axios with headers 'Content-Type': 'multipart/form-data'.

However, axios sends an empty body if I pass 'Content-Type': 'multipart/form-data' in the headers. If I remove it, it sends the actual object but without the uploaded file. I am implementing this on NextJs with Laravel backend.

Here's the code

      const formData = new FormData();
      formData.append('first_name', values.first_name);
      formData.append('last_name', values.last_name);
      formData.append('phone_no', values.phone_no);
      formData.append('profile_picture', values.profile_picture, 'bermuda.png');
      formData.append('password', values.password);

      await axios
        .put(`/api/v1/users/${user.member_no}`, formData, 
         {
           headers: {'Content-Type': 'multipart/form-data'}
         })
        .then((res) => {
          console.log(res.data);
          if (res.status === 201) {
            toast.success('Member updated successfully.');

            refreshUser(); // mutating the swr request
          }
        })
        .catch((err) => {
          toast.error(err.response.data.message);
        });

      setLoading(false);
    },

console.log(res.data) from axios returns [] if I pass multipart/form-data or it returns the whole value object if i remove it but wihout the uploaded file.


Solution

  • This seems to be a common re-occurring problem within Laravel projects. Not sure if it's caused by Axios or Laravel itself, but for the meantime, the following workaround works:

    Instead of sending an actual HTTP PUT request, send an HTTP POST request with a parameter in your formData named _method with its value set to put. This is a feature in Laravel known as method spoofing.

    Adding that field to your formData, your code would look like this:

          const formData = new FormData();
          formData.append('_method', 'put');
          formData.append('first_name', values.first_name);
          formData.append('last_name', values.last_name);
          formData.append('phone_no', values.phone_no);
          formData.append('profile_picture', values.profile_picture, 'bermuda.png');
          formData.append('password', values.password);
    
          await axios
            .post(`/api/v1/users/${user.member_no}`, formData, 
             {
               headers: {'Content-Type': 'multipart/form-data'}
             })
            .then((res) => {
              console.log(res.data);
              if (res.status === 201) {
                toast.success('Member updated successfully.');
    
                refreshUser(); // mutating the swr request
              }
            })
            .catch((err) => {
              toast.error(err.response.data.message);
            });
    
          setLoading(false);
        },