Upload file with multer in Nodejs
Tags: react, javascript, node
Published: 2019-12-09 23:23:20

# Upload file in Nodejs with multer

In this arcticle, I want to show you how can I upload file in Nodejs with multer. And I using react for front-end. Now, let's started.

## Backend

Making new folder :
```bash
    mkdir upload-file
    cd upload-file
```
Create new package.json :
```bash
    upload-file >  npm init -y
```
Libary what we need for backend
```bash
   upload-file > npm i -s express multer uuid morgan
```
| Libary | Description |
|--------|-------------|
| express | Creating server |
| multer | Working with file in express |
| uuid | Creating guid for new name file |
| morgan | Logger middleware server |

Create new file server.js in root folder :
```bash
    upload-file > touch server.js
```

Ok ! Now, we are going to setup server in nodejs :
```javascript
    const express = require("express");
    const app = express();
    const multer = require("multer");
    const uuid = require("uuid");
    const morgan = require("morgan");
    const path = "./uploads";

    const storage = multer.diskStorage({
        destination: (req, file, cb) => {
            cb(null, path);
        },
        filename: (req, file, cb) => {
            cb(null, uuid.v4().toString() + "_" + file.originalname);
        }
    });

    const fileFilter = (req, file, cb) => {
        if (file.mimetype === "image/jpeg" || file.mimetype === "image/png") {
            cb(null, true);
        } else {
            cb("Type file is not access", false);
        }
    };

    const upload = multer({
        storage,
        fileFilter,
        limits: 1024 * 1024 * 5
    });

    app.use(morgan("dev"));
    app.use(express.json({ extented: false }));

    const PORT = process.env.PORT || 5000;
    app.listen(PORT, () => console.log(`Server is running in port ${PORT}`));
```


Ok, now we are going to setup for server and client start in one command. If we do that, we are going to add new library :
```bash 
   npm i -D conccurently
```
Edit package.json in backend :
```json
    "scripts": {
        "start": "node server.js",
        "server": "nodemon server.js",
        "client": "npm start --prefix client",
        "dev": "concurrently \"npm run server\" \"npm run client\""
    },
```
## Client
Add library axios for working with RESTful Api and making beautiful web with bootstrap in React :
```bash 
    npm i -s axios bootstrap
```
Go to package.json in client and add proxy config in last file. That is will make easy work with RESTful, so we don't need everytime we declare "http://localhost:5000/api/name" but when using this case we just need "/api/name" :
```json
    "proxy" : "http://localhost:5000"
```

Then, rewriting file App.js in client folder:
```javascript
    import React, { Component } from "react";
    import "bootstrap/dist/css/bootstrap.min.css";
    import axios from "axios";

    class App extends Component {
        state = {
            title: "",
            file: ""
        };

        handleOnChange = e => this.setState({ [e.target.name]: e.target.value });

        handleOnUploadFile = e => this.setState({ file: e.target.files[0] });

        handleOnSubmit = e => {
            e.preventDefault();
            const formData = new FormData();
            formData.append("title", this.state.title);
            formData.append("file", this.state.file);
            axios
            .post("/api/post", formData)
            .then(res => console.log(res.data))
            .catch(err => console.error(err));
        };

        render() {
            return (
                <div className="container">
                    <h1>Upload file in nodejs</h1>
                    <form onSubmit={this.handleOnSubmit} className="w-50">
                    <div className="form-group">
                        <input
                        type="text"
                        name="title"
                        value={this.state.title}
                        autoComplete="off"
                        className="form-control"
                        onChange={this.handleOnChange}
                        />
                    </div>
                    <div className="form-group">
                        <input
                        type="file"
                        name="file"
                        accept="image/*"
                        onChange={this.handleOnUploadFile}
                        />
                    </div>
                    <button type="submit" className="btn btn-danger">
                        Submit
                    </button>
                    </form>
                </div>
            );
        }
    }

    export default App;
```

Result : ![Result upload single file]
(https://raw.githubusercontent.com/hatuanem199801/upload-file-in-nodejs/master/test/result%20upload%20single%20file.PNG)

And finally, we are going to upload multiple file. I will change a little file App.js :

```javascript
    state = {
        title: "",
        files: ""
    };
    //...
    handleOnUploadFile = e => this.setState({ files: e.target.files });
    //...
    handleOnSubmit = e => {
        e.preventDefault();
        const formData = new FormData();
        for (const name in this.state) {
            if (name === "files") {
                for (let i = 0; i < this.state.files.length; i++) {
                    formData.append(name, this.state.files[i]);
                }
            }
            formData.append(name, this.state[name]);
        }
        axios
        .post("/api/posts", formData)
        .then(res => console.log(res.data))
        .catch(err => console.error(err));
    };
    ///...
    render() {
        return (
            ///...
            <div className="form-group">
                <input
                type="file"
                name="file"
                accept="image/*"
                onChange={this.handleOnUploadFile}
                multiple
                />
            </div>
            ///...
        )
    }
```

Result image : ![Upload multiple file](https://raw.githubusercontent.com/hatuanem199801/upload-file-in-nodejs/master/test/result%20upload%20multiple%20file.PNG)

And just like that. If I wrong something, please comment for implement this article. And one more, I just know a little English, so please sympathize with me.
This is link github repo [upload-file-in-nodejs](https://github.com/hatuanem199801/upload-file-in-nodejs)
Thanks for reading !
Have a good day !