Upload images in NodeJS with progress bar

Hetaram Prajapati
4 min readApr 4, 2021

Today we will see how to upload image in NodeJS and save image name in DB.

We have multiple way of uploading images i.e. upload images at third party storage i.e. cloudinary, AWS S3 bucket etc, store images in DB as BLOB or keep images in a folder of our project and store image name in DB. It’s a debate which option is good. Personally I prefer to store at third party storage, but here we will keep image in our project and store name of image in DB.

Technologies which we will be using here: NodeJS, Express, Angular, MongoDB

Let’s create backend first. Create a NodeJS project. Here I am not stating the steps to create NodeJS app to make this article as short as possible.

Once done with initial setup for your NodeJS project, install below modules.

multer : Will help to upload files (https://www.npmjs.com/package/multer)

sharp: Will help to process image, we will use it to reduce image size. (https://www.npmjs.com/package/sharp)

Create a public folder at root level and under it create sub folder img and user i.e. public -> img -> user

Now we will create a middleware in our project. Create a new folder middleware, under it create a file upload.js and add below code to it.

I have already added comment to every important line, please read them to under stand above code.

Now we will create a model where we will be defining our DB schema.

We have used mongoose to create schema as we are using MongoDB as DB. Here we have used only two fields name and profile_image to make this example as simple as possible.

Now create an controller folder at root level, under it we will create our user.controller.js file where we will write our business logic.

To access the profile image URL we need to do one thing in our entry file i.e. index.js

Add below line in index.js

app.use(‘/public’, express.static(‘./public/’))

Now we need to prepare route for our controller for that create routes folder at root level.

To reduce length of our entry file I always prefer to create an inde.js file in routes folder and then call routes in our entry file index.js

Now call routes in our index.js (entry file which is at root level) as per below

require(‘./routes’)(app)

We are done with our backend, now let’s start front end.

Create a new Angular project (I am using Angular 9) with below command

ng new project-name

Once it is ready, install bootstrap and add it in angular.json file under styles array as per below.

“styles”: [

“node_modules/bootstrap/scss/bootstrap.scss”,

“src/styles.scss”

],

First of all we will modify the app.module.ts file, here we will add two more modules i.e. ReactiveFormsModule, HttpClientModule, where ReactiveFormsModule will help in creating forms and HttpClientModule will help to make http client request.

Modify the environment file as per below.

Now we will create a service class in our app folder for that hit below command in app folder

ng g s app

Modify the service class as per below

Now we will modify the app.component.ts class as per below where we have logic for image preview, progress bar, upload image.

Here we have used event because with simple response we can not get the upload progress.

Let’s create a simple HTML, modify app.component.html as per below.

To make our progress bar look good and get the upload percentage at centre we have to use some CSS, please modify app.component.css file as per below

Above CSS we have already used in our HTML file at line number 27.

Finally we are done with all changes, let’s start MongoDB, NodeJS server and Angular server.

Below is the running demo

In above demo I have used slow 3G speed to slow down the network so we can clearly see the progress of upload image.

In demo we can see that size of selected image is 1.34 MB, but after upload when we have checked in public -> img -> user folder we found that the size of uploaded image is 52.3 KB. So we can clearly see how much differentiate is there in the size of original image and image processed from sharp module (from 1.34 MB to 52.3 KB).

In above image we can see entry in DB where we have stored only image name (profile_image), not complete URL or BLOB.

Conclusion

We have seen how to upload image with progress bar in our project and reduced the size of image using sharp module.

If you need complete example, please go through the github link below

--

--

Hetaram Prajapati

I am a technology enthusiast software developer with 3+ years of experience working with Angular, NodeJS, MongoDB, Java, Spring Boot.