File Upload in MERN Stack
Tags: webdev, mern, javascript, beginners
Published: 2024-06-26 09:21:16

In this blog, we will delve into the concept of file uploads, which is essential for any web application built using JavaScript. Specifically, in the MERN stack, I have used the multer package to store files from the frontend to the backend without any compression.

## Using Multer

Multer is an npm package used for handling file uploads **(multipart/form-data)**. It is a middleware that integrates seamlessly with Express.js applications.

### Steps for File Upload Using Multer


**1. Install Multer Package:**
First, install the multer package via npm:
```
npm install multer
```

**2. Upload Button:**
Instead of forms, I have handled the submit request through states in React.js:

```
<div>
  <input type="file" onChange={(event) => setImage(event.target.files[0])} />
</div>
```

Handled through forms:
```
<form onSubmit={handleSubmit} enctype="multipart/form-data">
  <input type="file" />
</form>
```

**3. Handle Submit Function:**
Here is the handleSubmit function in React.js:

```
const [image, setImage] = useState(null);

const handleSubmit = async (event) => {
  event.preventDefault();
  try {
    const formData = new FormData();
    // image is the state which has image details
    formData.append('file', image);
    var name;
    await axios.post("http://localhost:4100/upload", formData, {
      withCredentials: true,
    })
    .then((response) => {
      toast.success("Image uploaded successfully");
      name = response.data;
    });
  } catch (error) {
    console.log(error);
  }
};
```

### Backend Part

**4. Multer Setup:**
Create a folder named 'uploads/' on the server-side. Add the following code to app.js. Refer to your project's folder structure for a complete MERN stack application setup.

```
// Import multer
const multer = require('multer');
const path = require('path');

// Configure multer storage
const storage = multer.diskStorage({
  destination: (req, file, cb) => {
    cb(null, 'uploads/');
  },
  filename: (req, file, cb) => {
    cb(null, `${Date.now()}-${file.originalname}`);
  }
});
const upload = multer({ storage: storage });
```

**5. Upload API:**
Note: The form data should have the key name 'file' in order to access the file inside the form data.

```
app.post('/upload', upload.single('file'), (req, res) => {
  try {
    res.json({ message: 'File uploaded successfully', name: req.file.filename });
  } catch (error) {
    console.log(error);
  }
});
```

**6. Serve Static Files**

Once the files are uploaded to the backend, they should be accessible from the browser to render on the frontend. To serve static files, use the built-in middleware function in Express.js: express.static().

```
app.use('/uploads', express.static(path.join(__dirname, 'uploads')));
```

For example, if the link is "http://localhost:4100/uploads/example.jpg", in the /uploads API, it strips the file name alone and searches for it in the 'uploads' directory.

**7. Optional: ES Modules**
If you use CommonJS modules, the above code will work. If you are using ES modules, __dirname is not present by default. You need to create an equivalent for ES modules.

```
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
```
-----------------------------------------------------------------
Feel free to reach out if you have any questions or need further assistance. 😊📁✨