How To Upload Multiple files to Cloudinary in Nodejs using Promise.all
Tags: node, javascript, cloudinary, multer
Published: 2021-05-01 06:52:01

It has remained something confusing while perusing [Cloudinary](https://cloudinary.com/) documentation on how exactly do you upload multiple images, for most developers what they tend to do is to call the single file upload method on the SDK in a loop, while this seems to work at times it gets buggy when one of the files has to take more time than the other because of the size. To follow along the tutorial you can download the starter boilerplate nodejs with express code from [Github ](https://github.com/wonderfulolanrewaju/multi-file-uploader).

We need to add multer configuration to our server.js file, then use this to create an. upload middleware function.	

**First Acts**
```
//clone the repo
git clone https://github.com/wonderfulolanrewaju/multi-file-uploader/blob/master/package.json

//cd into the project
cd multi-file-uploader

//install all dependencies
yarn install

//install nodemon for server restart on save
yarn add -D nodemon

//install new dependencies
yarn add dotenv
```

**Second Acts**
```
//Add the following object to your package.json
//What this does is allow us to make our server restart on save and run our js file with Esm module so we can use import syntax

 "scripts": {
    "start": "node -r esm server.js",
    "dev: "nodemon -r esm server.js"
  },
```

**Third Acts: Change the top part of server.js**
```
import express from "express";
import cloudinary from "cloudinary";
import multer from "multer";
import dotenv from "dotenv";
dotenv.config();
const app = express();
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
const {
  NODE_ENV,
  PORT: productionPort,
  IP: productionIP,
  cloudinaryName,
  cloudinaryApiKey,
  cloudinaryApiSecret,
} = process.env;
const storage = multer.diskStorage({
  filename: function (req, file, cb) {
    cb(null, file.fieldname + "-" + Date.now());
  },
});

cloudinary.v2.config({
  cloud_name: cloudinaryName,
  api_key: cloudinaryApiKey,
  api_secret: cloudinaryApiSecret,
});

const upload = multer({ storage });

app.get("/", (req, res) => {
  return res.status(200).json({
    message: "Multiple uploader api",
  });
});

...
if (NODE_ENV === "production") {
...

```

**Acts Four**
What we do next is used the upload middleware function created from multer, this middleware's array method :  "upload.array(nameOfFilesFields, maxCount)" takes the name we want to call the file field and the maximum number of images it should allow for upload.
```
app.post("/images", upload.array("pictures", 10), async (req, res) => {
  try {
    let pictureFiles = req.files;
    //Check if files exist
    if (!pictureFiles)
      return res.status(400).json({ message: "No picture attached!" });
    //map through images and create a promise array using cloudinary upload function
    let multiplePicturePromise = pictureFiles.map((picture) =>
      cloudinary.v2.uploader.upload(picture.path)
    );
    // await all the cloudinary upload functions in promise.all, exactly where the magic happens
    **let imageResponses = await Promise.all(multiplePicturePromise);**
    res.status(200).json({ images: imageResponses });
  } catch (err) {
    res.status(500).json({
      message: err.message,
    });
  }
});
```

> You can run yarn dev. your app should be running on localhost:9000

You can make a request to http://localhost9000/images with the form-data request body type using pictures as field name a sample screenshot is shown below
![Response screenshot](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nqf37yeqbjo0ophnuj4e.png)
You can also view the sample response json on a [Public directory](https://multi-file-uploader.herokuapp.com/sampleresponse.json)


The completed version of the code is available on [Completed branch on Github](https://github.com/wonderfulolanrewaju/multi-file-uploader/tree/completed) and live version available on [Heroku](https://multi-file-uploader.herokuapp.com/).