How to upload an image with MERN Stack?

Rivaan Ranawat
6 min readJun 7, 2021

--

Pre Requisites:

  • PC with Node installed

Tools We Will Use:

  • ReactJS
  • Mongoose
  • Node.JS
  • Express
  • Cloudinary
  • Bootstrap
  • Axios

What are we trying to achieve?

As Elon Musk once said, “People work better when they know what they know what the goal is and why”. So our goal is to store the image in MongoDB and then retrieve it. We don’t need to answer the ‘why’ part of the question because that’s why you are here.

Our Plan & Why

So we have multiple ways to solve this problem of storing image. I will share two ways to solve this problem and the problem with one of them.

The First One:

We can convert the image we accept from the client and convert it to Buffer in our server. What is Buffer? It is just a pretty long text computer understands. We can store it pretty easily but fetching it can be a time taking task! And definitely we shouldn’t make our users wait for the images to load for more than 10 minutes, that’s not what good developers do. To summarise, we abandon this method because of inconvenience and low performance.

The Second One:

Second one is with the help of cloud-based storage management services. There are multiple options we can choose from. Some are stated below:

  • AWS Storage
  • Microsoft Azure Storage Explorer
  • MultCloud
  • CloudFuze
  • Firebase Storage
  • Cloudinary

For this tutorial, we are going to use Cloudinary because of it’s ease to use.

The Second Plan In Detail

In this plan, we first want to accept the input image from user. Using the input image, we will send it to Cloudinary for storage. Then, we will retrieve the image. So the doubt here is we will retrieve the image, that’s cool but in what form? Won’t it take more time again? Plus much more time than first plan because it is a third party app.

The simple answer is no. Cloudinary, as I’ve said before is easy to use. You will get a link to the image which you can use and display image.

Getting Started

Enough theory and talking, now let’s get into implementing this. So first of all, you need to set up MongoDB for Database and adding Node.js and React to our project.

Setting Up Backend

  • Adding Node.js to the project

So, first create a directory and inside the directory create a folder named backend or server. Migrate inside the server folder and use the terminal command npm init -y to add node to your project with the default settings.

  • Installing Necessary Libraries from (npm install <libName>)
  1. mongoose — for data modelling
  2. multer — for uploading files
  3. nodemon — automatically restarting the server when file changes(optional)
  4. express — creating your server
  • Running MongoDB

In this tutorial, I will be running MongoDB locally on my mac. You can use the online web and make the changes accordingly. Run this command in your terminal to get the mongodb running:

/Users/rivaanranawat/mongodb/bin/mongod — dbpath=/Users/rivaanranawat/mongodb-data

I will be using Robo 3T to view the data in the database. You can use MongoDB Atlas as well.

  • Adding Frontend

For frontend, we will be using ReactJS, to add React to your project, go back to the root folder and use the command:

npx create-react-app client

  • Axios:
npm install axios
  • Bootstrap in React:

To add Bootstrap to your project, use the command:

npm install react-bootstrap bootstrap

Code in the Backend

So first, we have to create a file called index.js in the server/client folder. Then, we have to load in all the modules we had installed before to the index.js file. But before doing that, we will have to configure the package.json file. The scripts tag has to be replaced with the code below:

“scripts”: {

“dev”: “nodemon index.js”,

“start”: “node index.js”

}

Get to index.js file and load in express and mongoose modules as shown below:

app is an instance of the express package.

The next step is to start and listen to the server and connect to our local mongodb database. This can be done with the code mentioned below:

app.use converts all the responses given to us in json format. After that, we start listening to the server with the app.listen callback method. Then, we just connect to mongodb with the mongoose.connect method. Note the url should be the same except the path. The path is the name of your database for that project.

Creating a Model

The next thing is to create a model. This can be achieved using mongoose. So create a file named image.js inside a new model folder. Check the code below.

With this code, we have create a model named Image with a property of image which is a String(as I discussed earlier, the image url given to us by Cloudinary after uploading an image is String)

Creating API

Our next job is to create an api or a route which we will call from the client side to upload the image url. So in the server or backend folder, create a new folder named routes and create a new file named imageRoute.js and copy the code below.

This file basically creates a post request on store-image route and stores an Image collection with document as image in our mongodb.

Now, we’re done with the backend! Let’s move to the front end part!

Inputting File From User

Our first task after the setup for front-end is to input the file from the user. So, we need to give user a button to add file from their system.

Note: I am assuming you have removed unnecessary files from React and your App.js is empty. We will be using Functional Components to do this task.

First of all, create a new folder named components inside which you can create a new file called AddImage.js and return the following ui.

Observe the Form.File tag, we put a property of accept as “image/*” which accepts only images from the user’s pc and on change of image we set a new image to the hook we create above the return like this:

const [error, setError] = useState();

const [image, setImage] = useState();

Setting Up Cloudinary

To set up Cloudinary, head over to https://cloudinary.com and sign up for an account. You’ll get redirected to Cloudinary Dashboard. Click on the settings icon in the top right corner. Click on the upload tab and scroll down to see Upload Presets settings. Click on add Upload Preset and change the settings to this.

Change Signing Mode, Folder name and upload preset name.

Note the upload preset name, will come handy in future. Click Save Button and save changes.

Let’s get back to writing code. handleSubmit function isn’t defined yet, so let’s defined the handleSubmit function like this:

The presetName is the name I asked you to remember some time ago and yourUrl is the api base url given on the dashboard. In this function we send a post request using axios to cloudinary which returns a url to us and then a post request to the api we created before.

Now, you can run the command cd client && npm start to see if the image url gets stored in the database.

Displaying Image(Bonus)

As we all know, displaying an image from a url is very easy. We just have to get the id of the image from the database and then display it using the <img /> tag or if using Bootstrap <Image /> or if in Card <Card.Img/>

So we are done! We have succesfully added image in our database and can display them. Let me know if you can display the images in the comments!

If any issue, let me know in the comments.

Thank You for Reading!

--

--

Rivaan Ranawat

Hello There! I am Rivaan Ranawat, 19 year old coding enthusiast.