In this blog post, we will walk you through creating a simple file upload and display feature using the MERN stack. We will use Multer for handling file uploads on the server side with Node.js and Express and React for the front end to allow users to select and upload files.

Prerequisites

Before we start, make sure you have the following installed:

  • Node.js and npm
  • Basic knowledge of React and Node.js

Setting Up the Backend with Node.js and Express

First, set up the backend server using Node.js, Express, and Multer.

Step 1: Install Dependencies

Run the following command to install the necessary packages:

bashCopy codenpm install express multer cors

Step 2: Create the Server

Create a file named server.js And add the following code:

javascriptCopy codeconst express = require('express');
const multer = require('multer');
const path = require('path');
const cors = require('cors');
const fs = require('fs');

const app = express();
const PORT = 3001;

app.use(cors());

// Multer configuration
const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, 'uploads/');
  },
  filename: function (req, file, cb) {
    cb(null, file.originalname);
  }
});

const upload = multer({ storage });

// File upload endpoint
app.post('/upload', upload.single('file'), (req, res) => {
  if (!req.file) {
    return res.status(400).send('No files were uploaded.');
  }
  console.log(req.file);
  res.send('File uploaded successfully.');
});

// File download endpoint
app.get('/download/:filename', (req, res) => {
  const fileName = req.params.filename;
  const filePath = path.join(__dirname, 'uploads', fileName);

  try {
    if (fs.existsSync(filePath)) {
      res.sendFile(filePath);
    } else {
      res.status(404).send('File not found.');
    }
  } catch (error) {
    console.error('Error downloading file:', error);
    res.status(500).send('Internal server error.');
  }
});

// File delete endpoint
app.delete('/delete/:filename', (req, res) => {
  const fileName = req.params.filename;
  const filePath = path.join(__dirname, 'uploads', fileName);

  try {
    if (fs.existsSync(filePath)) {
      fs.unlinkSync(filePath);
      res.send('File deleted successfully.');
    } else {
      res.status(404).send('File not found.');
    }
  } catch (error) {
    console.error('Error deleting file:', error);
    res.status(500).send('Internal server error.');
  }
});

// Start the server
app.listen(PORT, () => {
  console.log(`Server is running on http://localhost:${PORT}`);
});

This code sets up an Express server with endpoints for uploading, downloading, and deleting files using Multer to handle file uploads.

Setting Up the Frontend with React

Next, let’s create the React frontend to interact with our server.

Step 1: Create a React App

If you don’t already have a React application, you can create one using Create React App:

bashCopy codenpx create-react-app mern-file-upload
cd mern-file-upload

Step 2: Install Axios

We’ll use Axios to make HTTP requests to our backend. Install Axios with the following command:

bashCopy codenpm install axios

Step 3: Create the React Component

Replace the content of src/App.js With the following code:

javascriptCopy codeimport React, { useState } from 'react';
import axios from 'axios';
import './App.css';

function App() {
  const [selectedFile, setSelectedFile] = useState(null);

  const handleFileChange = (e) => {
    setSelectedFile(e.target.files[0]);
  };

  const handleSubmit = async () => {
    try {
      const formData = new FormData();
      formData.append('file', selectedFile);

      await axios.post('http://localhost:3001/upload', formData, {
        headers: {
          'Content-Type': 'multipart/form-data',
        },
      });

      console.log('File uploaded successfully');
    } catch (error) {
      console.error('Error uploading file:', error);
    }
  };

  return (
    <>
      <h1>How to Upload File Using Multer</h1>
      <img src='http://localhost:3001/download/image.png' height={100} alt='Uploaded'/>
      <div className="card">
        <h2>Upload File</h2>
        <input type="file" onChange={handleFileChange} />
        <button onClick={handleSubmit}>Upload</button>
      </div>
      <p className="read-the-docs">
        Video by : Web Codder
      </p>
    </>
  );
}

export default App;

This code creates a simple React component with a file input and a button to upload the selected file. When the file is selected, it is stored in the component’s state. The file is sent to the backend using Axios when the upload button is clicked.

Step 4: Styling (Optional)

You can add some basic styling in src/App.css to make the application look nicer:

cssCopy code.card {
  margin: 20px;
  padding: 20px;
  border: 1px solid #ccc;
  border-radius: 8px;
}

h1, h2 {
  text-align: center;
}

button {
  display: block;
  margin: 20px auto;
  padding: 10px 20px;
  font-size: 16px;
}

input {
  display: block;
  margin: 10px auto;
}

Running the Application

To run the application, follow these steps:

  1. Start the backend server:
bashCopy codenode server.js
  1. Start the React frontend:
bashCopy codenpm start

Visit http://localhost:3000 in your browser. You should see the upload interface, and you can upload files, which will be handled by the backend server.

Download Source Code

Conclusion

This tutorial taught us how to create a simple file upload feature using the MERN stack. We set up an Express server with Multer to handle file uploads and created a React front to interact with the server. This basic setup can be expanded and customized to fit more complex requirements, such as adding authentication, displaying uploaded files, and more.

Feel free to ask questions or share your thoughts in the comments below. Happy coding!

Categorized in: