14

I'm trying upload multiple images with axios in React but i cannot figure out what is wrong. First I tried to upload single image and that work just fine. But with multiple images I'm out of options.

I'm creating FormData like so:

for (let i = 0; i < images.length; i++) {
    formData.append('productPhotos[' + i + ']', images[i]);
}

The axios request looking like this

    const config = { headers: { 'Content-Type': 'multipart/form-data' } };

    axios
        .post(endPoints.createProduct, formData, config)
        .then(res => console.log(res))
        .catch(err => console.log(err));

My back-end is written is node/express and I'm using multer for uploading. The signature is look like this:

app.post("/product", upload.array("productPhotos"), (req, res) => {

I tried this back-end end point in PostMan and uploading works for just fine, so the error must be on front-end. Thanks for help.

UPDATE Right way to pass multiple files in formData:

images.forEach(img => {
    formData.append("productPhotos", img)
})
3
  • 1
    What is images? Commented Oct 14, 2019 at 18:32
  • Array of files from image chooser. Commented Oct 14, 2019 at 18:44
  • Thanks for your answer. I was using the FileList object instead File object. But your answer make me think about that, thanks :) Commented Oct 14, 2019 at 18:53

3 Answers 3

34

Here is a full working set up (expanded version of the answer above)

Client side:

// silly note but make sure you're constructing files for these (if you're recording audio or video yourself)
// if you send it something other than file it will fail silently with this set-up 
let arrayOfYourFiles=[image, audio, video]
// create formData object
const formData = new FormData();
arrayOfYourFiles.forEach(file=>{
  formData.append("arrayOfFilesName", file);
});

axios({
  method: "POST",
  url: serverUrl + "/multiplefiles",
  data: formData,
  headers: {
    "Content-Type": "multipart/form-data"
  }
})
//some error handling

Server side (express, node - mutler)

const UPLOAD_FILES_DIR = "./uploads";
const storage = multer.diskStorage({
  destination(req, file, cb) {
    cb(null, UPLOAD_FILES_DIR);
  },
// in case you want to change the names of your files)
  filename(req, file = {}, cb) {
    file.mimetype = "audio/webm";
    // console.log(req)
    const {originalname} = file;
    const fileExtension = (originalname.match(/\.+[\S]+$/) || [])[0];
    cb(null, `${file.fieldname}${Date.now()}${fileExtension}`);
  }
});
const upload = multer({storage});

// post route that will be hit by your client (the name of the array has to match)
app.post("/multiplefiles", upload.array('arrayOfFilesName', 5), function (req, res) {
  console.log(req.files, 'files')
  //logs 3 files that have been sent from the client
}
Sign up to request clarification or add additional context in comments.

3 Comments

What is 'answerFormData' on the client side? It looks like its undefined.
On line 3 of the 'client side' ... what type of object is the 'image, audio, video' files? Are they file paths?
@lowcrawler you can construct them by doing var someFile= new File([blob], name + ".extension", { contentType: "some/type" });
2

You may want to send the files as an array to the endpoint:

images.forEach( img => {
formData.append('productPhotos[]', img);
})

Comments

0

This is not the right way to generate keys. You can try something like this:

let productimages = [];

for (let i = 0; i < images.length; i++) {
    productimages.push(images[i]);
}
formData.append('productPhotos', productimages);

1 Comment

Yes this works fine. I was using the FileList object instead File object and that was the real problem. Thanks for your answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.