In this blog, we will explore how to upload multiple files using Node.js and Express with the Multer library. We will create both the backend server and the frontend interface to handle file uploads. By the end of this tutorial, you will have a fully functional application that can upload multiple files at once.

Prerequisites

  • Basic understanding of Node.js and Express
  • Familiarity with React for the frontend
  • Node.js and npm installed on your machine

Setting Up the Project

Step 1: Initialize the Node.js Project

First, create a new directory for your project and initialize a Node.js project.

bashCopy codemkdir file-upload-multiple
cd file-upload-multiple
npm init -y

Step 2: Install Required Packages

Install Express, Multer, and Cors packages.

bashCopy codenpm install express multer cors

Backend Setup

Step 3: Create the Server

Create a file named server.js and set up your Express server.

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

const app = express();
app.use(cors());

// Set up storage engine
const storage = multer.diskStorage({
    destination: (req, file, cb) => {
        cb(null, './uploads');
    },
    filename: (req, file, cb) => {
        cb(null, file.originalname);
    }
});

// Initialize multer with storage settings
const upload = multer({ storage });

// Define route for file uploads
app.post('/upload', upload.array('files', 10), (req, res) => {
    console.log('Uploading', req.files);
    res.send('File Uploaded');
});

// Define route for the homepage
app.get('/', (req, res) => {
    res.send('Server by Web Codder');
});

// Start the server
app.listen(3001, () => {
    console.log('Server is running on port 3001');
});

Frontend Setup

Step 4: Create the React Application

Create a React application using Create React App.

bashCopy codenpx create-react-app client
cd client
npm start

Step 5: Set Up File Upload Component

Inside the src directory, replace the content of App.js with the following code:

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

function App() {
  const [selectedFiles, setSelectedFiles] = useState([]);

  const updateFile = (e) => {
    setSelectedFiles(e.target.files);
    console.log(e.target.files);
  };

  const sendFiles = async () => {
    try {
      const formData = new FormData();
      Array.from(selectedFiles).forEach(file => {
        formData.append('files', file);
      });

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

      if (res) {
        console.log(res);
      }
    } catch (error) {
      console.log(error);
    }
  };

  return (
    <>
      <div className='card'>
        <input type='file' onChange={updateFile} multiple />
        <button onClick={sendFiles}>Upload Now</button>
      </div>
    </>
  );
}

export default App;

Detailed Explanation

Backend Code Breakdown

  1. Setup and Middleware:
    • express to create the server.
    • multer to handle file uploads.
    • cors to allow cross-origin requests.
    javascriptCopy codeconst express = require('express'); const multer = require('multer'); const cors = require('cors'); const app = express(); app.use(cors());
  2. Multer Configuration:
    • Define storage options, including destination and filename.
    javascriptCopy codeconst storage = multer.diskStorage({ destination: (req, file, cb) => { cb(null, './uploads'); }, filename: (req, file, cb) => { cb(null, file.originalname); } }); const upload = multer({ storage });
  3. Routes:
    • POST /upload: Handles file uploads.
    • GET /: Simple endpoint to verify server functionality.
    javascriptCopy codeapp.post('/upload', upload.array('files', 10), (req, res) => { console.log('Uploading', req.files); res.send('File Uploaded'); }); app.get('/', (req, res) => { res.send('Server by Web Codder'); });
  4. Server Initialization:
    • Start the server on port 3001.
    javascriptCopy codeapp.listen(3001, () => { console.log('Server is running on port 3001'); });

Frontend Code Breakdown

  1. State Management:
    • Use useState to manage selected files.
    javascriptCopy codeconst [selectedFiles, setSelectedFiles] = useState([]);
  2. File Selection Handler:
    • Update state when files are selected.
    javascriptCopy codeconst updateFile = (e) => { setSelectedFiles(e.target.files); console.log(e.target.files); };
  3. File Upload Function:
    • Create a FormData object and append selected files.
    • Use Axios to send POST request to the server.
    javascriptCopy codeconst sendFiles = async () => { try { const formData = new FormData(); Array.from(selectedFiles).forEach(file => { formData.append('files', file); }); const res = await axios.post('http://localhost:3001/upload', formData, { headers: { 'Content-Type': 'multipart/form-data', }, }); if (res) { console.log(res); } } catch (error) { console.log(error); } };
  4. Component Rendering:
    • Render file input and upload button.
    javascriptCopy codereturn ( <> <div className='card'> <input type='file' onChange={updateFile} multiple /> <button onClick={sendFiles}>Upload Now</button> </div> </> );

Testing the Application

  1. Start the backend server:bashCopy codenode server.js
  2. Start the React application:bashCopy codecd client npm start
  3. Open your browser and navigate to http://localhost:3000.
  4. Select multiple files and click “Upload Now”.
  5. Check the console for uploaded file details.

Download the Source Code

You can download the complete source code for this project from the following link:

Conclusion

Congratulations! You have successfully created a Node.js and Express server with Multer to handle multiple file uploads, and a React frontend to interact with it. This functionality is essential for modern web applications, and you can further expand it with additional features like file validation and user authentication.

If you have any questions or comments, feel free to leave them below. Happy coding!

Categorized in: