DEV Community

Cover image for Upload file with multer in Nodejs
Ha Tuan Em
Ha Tuan Em

Posted on • Edited on

Upload file with multer in Nodejs

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 :

    mkdir upload-file
    cd upload-file
Enter fullscreen mode Exit fullscreen mode

Create new package.json :

    upload-file >  npm init -y
Enter fullscreen mode Exit fullscreen mode

Libary what we need for backend

   upload-file > npm i -s express multer uuid morgan
Enter fullscreen mode Exit fullscreen mode
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 :

    upload-file > touch server.js
Enter fullscreen mode Exit fullscreen mode

Ok ! Now, we are going to setup server in nodejs :

    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}`));
Enter fullscreen mode Exit fullscreen mode

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 :

   npm i -D conccurently
Enter fullscreen mode Exit fullscreen mode

Edit package.json in backend :

    "scripts": {
        "start": "node server.js",
        "server": "nodemon server.js",
        "client": "npm start --prefix client",
        "dev": "concurrently \"npm run server\" \"npm run client\""
    },
Enter fullscreen mode Exit fullscreen mode

Client

Add library axios for working with RESTful Api and making beautiful web with bootstrap in React :

    npm i -s axios bootstrap
Enter fullscreen mode Exit fullscreen mode

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" :

    "proxy" : "http://localhost:5000"
Enter fullscreen mode Exit fullscreen mode

Then, rewriting file App.js in client folder:

    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;
Enter fullscreen mode Exit fullscreen mode

Result : Result upload single file

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

    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>
            ///...
        )
    }
Enter fullscreen mode Exit fullscreen mode

Result image : Upload multiple file

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
Thanks for reading !
Have a good day !

Top comments (1)

Collapse
 
d0m00re profile image
d0m00re

Heyn thank's foryour work.

The current github link is dead :/