React Tutorial- React Single Upload Tutorial With Multer, Node, Express

This react tutorial will teach us how to upload a single file in a react app. Using the Node server, we will also learn how to store image files in the MongoDB database.

We will learn to upload a single image file and store that file in the MongoDB database using Node and React.js. We will learn to create a client-side basic React app. We will also create a file upload API with Express, Multer and Node packages.

 

React Node Multer File Upload Example

Step 1- Install React App

Step 2- Create React File Upload Component

Step 3- Create Node Server

Step 4- Create Schema 

Step 5- Set Up Express Routes

Step 6- Set Up Server Js

Step 7- Test React File Upload API

Step 8- Build React Single File Upload

 

First of all, we have to install and set up React app for the file upload demo.

 

Step 1- Install React App

We have to enter the given command in the terminal to install a new React app:

npx create-react-app react-node-file-upload

Then, we will go to the project folder:

cd react-node-file-upload

Now, we will start our React app in the web browser:

npm start

Here, we need to install Bootstrap 4 in React app:

npm install bootstrap --save

Afterward, we include the bootstrap.min.css in the src/App.js file:

import React from 'react';
import '../node_modules/bootstrap/dist/css/bootstrap.min.css';
function App() {
  return (
    <div className="App">
      <h2>React File Upload Demo</h2>
    </div>
  );
}
export default App;

 

Step 2- Create React File Upload

Now, we will head over to the src>components directory and create a separate file by the name of files-upload-component.js:

import React, { Component } from 'react';
export default class FilesUploadComponent extends Component {
    render() {
        return (
            <div className="container">
                <div className="row">
                    <form>
                        <h3>React File Upload</h3>
                        <div className="form-group">
                            <input type="file" />
                        </div>
                        <div className="form-group">
                            <button className="btn btn-primary" type="submit">Upload</button>
                        </div>
                    </form>
                </div>
            </div>
        )
    }
}

Then, we add the FilesUploadComponent in the App.js template:

import React, { Component } from 'react';
import '../node_modules/bootstrap/dist/css/bootstrap.min.css';
import './App.css';
import FilesUploadComponent from './components/files-upload-component';
class App extends Component {
  render() {
    return (
      <div className="App">
        <FilesUploadComponent />
      </div>
    );
  }
}
export default App;

 

Step 3- Create Node Server

Here, we will build the server with Node, Express, MongoDB and Multerfor React file upload tutorial. We need to create the backend folder inside the React project.

Further, we will execute the command to generate the backend folder and get into the project folder:

mkdir backend && cd backend

We build a separate package.json file for Node Server:

npm init

 

We will be using the following Node modules to build Node/Express Server:

NPM                                                                   Detail

Express                      A web application framework for Node.js.

MongoDB                NoSQL database based on document and collect format.

CORS                        Supports Access-Control-Allow-Origin CORS header.

bodyParser            A body parsing middleware for Node.js.

uuid                        Simple, fast generation of RFC4122 UUIDS.

Multer                    A Node.js middleware handles multipart/form-data, best used of file uploading.

 

Then, we run the command to install NPM packages:

npm install mongoose express cors body-parser uuid@^3.4.0 multer

Then, we install nodemon to auto-restart the node server, whenever it detects change in the server files.

 

Step 4- Create Schema

Afterward, we create a backend>models directory and create a fresh file inside of it and name it User.js:

const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const userSchema = new Schema({
    _id: mongoose.Schema.Types.ObjectId,
    profileImg: {
        type: String
    }
}, {
    collection: 'users'
})
module.exports = mongoose.model('User', userSchema)

We declared profileImg value with String data type along with Mongoose _id in Mongoose Schema file.

 

Step 5- Set Up Express Routes

In this step, we will create a backend>routes folder and create a new file inside of it and name it user.routes.js:

let express = require('express'),
    multer = require('multer'),
    mongoose = require('mongoose'),
    uuidv4 = require('uuid/v4'),
    router = express.Router();
const DIR = './public/';
const storage = multer.diskStorage({
    destination: (req, file, cb) => {
        cb(null, DIR);
    },
    filename: (req, file, cb) => {
        const fileName = file.originalname.toLowerCase().split(' ').join('-');
        cb(null, uuidv4() + '-' + fileName)
    }
});
var upload = multer({
    storage: storage,
    fileFilter: (req, file, cb) => {
        if (file.mimetype == "image/png" || file.mimetype == "image/jpg" || file.mimetype == "image/jpeg") {
            cb(null, true);
        } else {
            cb(null, false);
            return cb(new Error('Only .png, .jpg and .jpeg format allowed!'));
        }
    }
});
// User model
let User = require('../models/User');
router.post('/user-profile', upload.single('profileImg'), (req, res, next) => {
    const url = req.protocol + '://' + req.get('host')
    const user = new User({
        _id: new mongoose.Types.ObjectId(),
        name: req.body.name,
        profileImg: url + '/public/' + req.file.filename
    });
    user.save().then(result => {
        res.status(201).json({
            message: "User registered successfully!",
            userCreated: {
                _id: result._id,
                profileImg: result.profileImg
            }
        })
    }).catch(err => {
        console.log(err),
            res.status(500).json({
                error: err
            });
    })
})
router.get("/", (req, res, next) => {
    User.find().then(data => {
        res.status(200).json({
            message: "User list retrieved successfully!",
            users: data
        });
    });
});
module.exports = router;

Then, we create a backend>public folder, in this folder, we will store all the image files uploaded by the user.

We, now, run the given command from the root of the backend project:

mkdir public

 

Step 6- Set Up Server Js

In this step, we create a backend>index.js file and paste the following code into it. This file contains required server settings such as database, express configuration, PORT connection, etc:

let express = require('express'),
    mongoose = require('mongoose'),
    cors = require('cors'),
    bodyParser = require('body-parser');
const api = require('../backend/routes/user.routes')
// MongoDB Configuration
mongoose
  .connect('mongodb://127.0.0.1:27017/mydatabase')
  .then((x) => {
    console.log(`Connected to Mongo! Database name: "${x.connections[0].name}"`)
  })
  .catch((err) => {
    console.error('Error connecting to mongo', err.reason)
  })
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
    extended: false
}));
app.use(cors());
app.use('/public', express.static('public'));
app.use('/api', api)
const port = process.env.PORT || 4000;
const server = app.listen(port, () => {
    console.log('Connected to port ' + port)
})
app.use((req, res, next) => {
    // Error goes via `next()` method
    setImmediate(() => {
        next(new Error('Something went wrong'));
    });
});
app.use(function (err, req, res, next) {
    console.error(err.message);
    if (!err.statusCode) err.statusCode = 500;
    res.status(err.statusCode).send(err.message);
});

 

Step 7- Test React File Upload API

In this step, we will test the REST API which we just created, before that we need to start the Node Server. We have to follow the given process to start the Node/Express Server.

We will run the command to start the MongoDB:

mongod

Here, we run the nodemon server by executing the given command:

nodemon server

Method              API URL

GET                     http://localhost:4000/api

POST                   /api/user-profile

 

Step 8- Build React Single File Upload

Now, we have to install the React Axios Library.

npm install axios

Then, we will add the given code in the src/components/files-upload.component.js file:

import React, { Component } from 'react';
import axios from 'axios';
export default class FilesUploadComponent extends Component {
    constructor(props) {
        super(props);
        this.onFileChange = this.onFileChange.bind(this);
        this.onSubmit = this.onSubmit.bind(this);
        this.state = {
            profileImg: ''
        }
    }
    onFileChange(e) {
        this.setState({ profileImg: e.target.files[0] })
    }
    onSubmit(e) {
        e.preventDefault()
        const formData = new FormData()
        formData.append('profileImg', this.state.profileImg)
        axios.post("http://localhost:4000/api/user-profile", formData, {
        }).then(res => {
            console.log(res)
        })
    }

    render() {
        return (
            <div className="container">
                <div className="row">
                    <form onSubmit={this.onSubmit}>
                        <div className="form-group">
                            <input type="file" onChange={this.onFileChange} />
                        </div>
                        <div className="form-group">
                            <button className="btn btn-primary" type="submit">Upload</button>
                        </div>
                    </form>
                </div>
            </div>
        )
    }
}

 

  • We declared the constructor and set the profileImg state and bind the events.
  • Inside the file input field, we passed the onChange event along with the onSubmit method on the form.
  • In the onSubmit method, we manage the file value using the FormData interface and then we are making the HTTP POST request using the Axios post() method.

Conclusion

So, now we have reached the completion of React File Upload with Node/Express Js Tutorial. In this, we have learned how to upload a single file in React app and store the images in the MongoDB database using the Node server.

 

Thanks

Leave a Reply

Your email address will not be published. Required fields are marked *