Search code examples
reactjsarraysaxiosmultipartform-data

React Axios multipart/form-data Array not Working


I am trying to send a collection of data through Axios which contains image, so I have to use multipart/form-data. When I try to send an array data, the result I got is just an empty array. I am using Axios version 1.6.5, it should have Automatic serialization. I have no idea what am I missing. This is my code in React.js:

import AxiosInstance from "../Axios";
.....
AxiosInstance.post(`manager/`, {
  title: data.title,
  url: data.url,
  date: date,
  category: data.category,
  level: ["easy", "medium"], //to make sure I send array 
  scope: data.scope,
  image: data.image,
  description: data.description,
}).then((res) => {
    console.log(res);
});

This is what I got in the result:

data: 
  category: false
  created: "2024-01-27T17:58:38.028124Z"
  date: "2024-01-31"
  description: "Testing only"
  id: 17
  image: "http://127.0.0.1:8000/images/manager/Testing.jpg"
  level: []
  scope: true
  slug: "test"
  title: "test"
  updated: "2024-01-27T17:58:38.028124Z"
  url: "https://test.com

I tried to send the data from Postman to make sure it was not my backend problem and I worked fine. This is what I tried in Postman enter image description here

How to implement this in the Axios? What am I missing?

I really appreciate your help, thank you in advance!


Solution

  • You can use FormData() It supportarray data like level: ["easy", "medium", "hard"] in React Component

    Snippet code

    const [levels, setLevels] = useState(["easy", "medium", "hard"]);
    const formData = new FormData();
    levels.forEach(level => formData.append('level[]', level));
    
    const response = await axios.post('http://localhost:3001/manager', formData, {
       headers: {
          'Content-Type': 'multipart/form-data'
       }
    });
    

    OR New Automatic serialization method

    const [levels, setLevels] = useState(["easy", "medium", "hard"]);
    const [image, setImage] = useState("http://127.0.0.1:8000/images/manager/Testing.jpg");
    
    const formData = {
        levels: levels,
        image: image
    };
    
    const response = await axios.post('http://localhost:3001/manager', formData, {
        headers: {
            'Content-Type': 'multipart/form-data'
        }
    });
    

    Demo

    #1 node.js Server using express library

    Specially multer library support form-data Save as server.js

    const express = require('express');
    const cors = require('cors');
    const multer = require('multer');
    
    const app = express();
    const upload = multer();
    app.use(express.json());
    
    // Middlewares
    app.use(cors()); // For cross-origin resource sharing
    
    app.post('/manager', upload.none(), (req, res) => {
        const levels = req.body.level;
        const image = req.body.image;
        // Other passing data add in here
        // ex) title = req.body.title;
    
        console.log('Received levels:', levels);
        console.log('Received image:', image);
    
        // Handle your array data and image as needed here
        // ...
    
        // Sending back a JSON response
        res.json({ levels: levels, image: image });
    });
    
    
    // Server listening
    const PORT = process.env.PORT || 3001;
    app.listen(PORT, () => {
        console.log(`Server running on port ${PORT}`);
    });
    

    Install server Dependencies

    npm install express cors multer
    

    Run Server

    node server.js
    

    POST Call Testing by Postman

    To check array and image URL testing

    enter image description here


    FormComponent in React

    import React, { useState } from 'react';
    import axios from 'axios';
    
    const FormComponent = () => {
        const [levels, setLevels] = useState(["easy", "medium", "hard"]);
        const [image, setImage] = useState("http://127.0.0.1:8000/images/manager/Testing.jpg");
    
        const [responseMessage, setResponseMessage] = useState('');
    
        const handleSubmit = async (event) => {
            event.preventDefault();
    
            const formData = {
                levels: levels,
                image: image
            };
    
            try {
                const response = await axios.post('http://localhost:3001/manager', formData, {
                    headers: {
                        'Content-Type': 'multipart/form-data'
                    }
                });
                console.log(response.data);
                setResponseMessage(JSON.stringify(response.data, null, 2)); // Formatting JSON for display
            } catch (error) {
                console.error('There was an error!', error);
                setResponseMessage('Error: Could not get a response.');
            }
        };
    
        return (
            <div>
                <form onSubmit={handleSubmit}>
                    <button type="submit">Submit Levels</button>
                </form>
                {responseMessage && <p>Server Response: {responseMessage}</p>}
            </div>
        );
    };
    
    export default FormComponent;
    

    Before Post Call (or Before button click)

    enter image description here

    After Post Call

    enter image description here