How to upload files with multer in your MERN App
Tags: react, javascript, node, webdev
Published: 2022-07-27 15:07:58

File upload is a common operation for any applications. In Node.js, with the Express web framework and the Multer library, adding file upload feature to your app is very easy. In this tutorial, we are going to learn how to upload files on the server with the help of Multer and Express in Node.js and display it in React App. At the end of this blog, you will be able to integrate the file uploads in your own apps.
## **What is Multer?**
Multer is a node.js middleware for handling multipart/form-data, which is primarily used for uploading files. It is written on top of the busyboy, for maximum efficiency. By this, you can understand that multer is used to handle multipart/form-data.
**

## What is Multipart Data?
**
When a “form” is submitted, browsers use “application-xx-www-form-urlencoded” content-type. This type contains only a list of keys and values and therefore are not capable of uploading files. Whereas, when you configure your form to use “multipart/form-data” content-type, browsers will create a “multipart” message where each part will contain a field of the form. A multipart message will consist of text input and file input. This way using multipart/form-data you can upload files.

Multer adds a body object and a file or files object to the request object. The body object contains the values of the text fields of the form, the file or files object contains the files uploaded via the form.

Multer will not process any form which is not multipart (multipart/form-data).
Now Let's dive into the code..
First of all you need to install multer in your Node.js app following this command:

```
//installation of multer module
npm install multer --save
```
in this project we will store files into a folder named "images" in the "public" folder.
We will create a files named "upload.js" (named as you like) and load multer in it, i'm using the import method if you work with require feel free.
`import multer from 'multer';`
**DiskStorage**
The disk storage engine gives you full control over storing files to disk. We will create a storage object using the diskStorage() method.
The following code will go in **upload.js**

```
const storage = multer.diskStorage({
    destination: function (req, file, cb) {
        cb(null, './public/images');
    },
    filename: function (req, file, cb) {
        cb(null, Date.now() + "--" + file.originalname);
    }
});  
```
There are two properties, destination, and filename. They both are functions.

**destination** - It can also be given as a string (e.g. './public/images'). If no **destination** is given, the operating system's default directory for temporary files is used. It is mandatory to create a directory when you are using destination as a function. Otherwise, if you are using destination as a string, multer will make sure that the directory is created for you.

**filename** - It is used to determine what the file should be named inside the folder. If you don't provide any filename, each file will be given a random name without any file extension. It is your responsibility to provide a function that should return a complete filename with a file extension. Both these functions take 3 arguments - the request object, the file object and a callback function (here, cb is callback function). The 2 arguments to cb are:

**null** : as we don’t want to show any error.
**file.originalname**: the name of the files where they are uploaded. 
We are going to use `Date.now() + "--" + file.originalname` 
to make sure the uniqueness of the files names.

```
let upload = multer({ 
storage: storage,
 limits : {fileSize : 3000000
});
```

Here, we have called the **multer() **method. It accepts an options object, with storage property, which tells Multer where to upload the files . and **limits** (it's an option not mandatory) to limit the fileSize. (1000000 bytes = 1mb).

**Other Options:**
**fileFilter** - Set this to a function to control which files should be uploaded and which should be skipped. The function should look like this:

```
const fileFilter = (req, file, cb) => {
    if((file.mimetype).includes('jpeg') || (file.mimetype).includes('png') || (file.mimetype).includes('jpg')){
        cb(null, true);
    } else{
        cb(null, false);
    }
};

```

`export default upload.single('file-demo')`

.single() is used for uploading a single file.

Note that the field name that you are providing in form data should be the same as the one provided in the **multer({..}).single()** (here the name is file-demo)

We have to export default the **upload** to use it as a middleware in the routes.
No go to the **routes** folder and add the following code:

```
import upload from "./upload.js";
const router = express.Router();
router.post('/', upload, (req, res) => {
   const file = req.file.filename;
   const newImage = {file-demo : file}
   try{
     await newImage.save();
     res.status(201).json(newimage );
   }catch(error){
     res.status(409).json({ message: error.message });
   }

});
```
to display the images in your react app use the following :

```
// the url of your api following /public/images/
const url_imgs = "http://localhost:3001/public/images/"
<img
   src={`${url_imgs}${demo-file}`}
   alt=""
   />
```

Now, we know how to integrate file upload using multer in any application. Go ahead! make your own application with complete frontend and integrate the file upload by using the above-acquired knowledge.

Don't Stop Learning!