Uploading Images to Your Node.js Backend

Andrew Richards
Jun 25, 2020 · 6 min read

While learning Node you may get to the point where you want to upload photos from your client to the backend. As someone who has struggled with Rails active storage in the past, I was delighted to find that uploading images to your server with Node is easy.

Node.js!

All it takes is an npm package, ‘Multer’, and a little bit of help from another package called ‘Sharp’.

Multer is a package maintained by the same people who maintain Express. So while Express does not have this feature built in, it is simple to add it.

So let’s get started:

Step 1: Install Multer

First head to https://www.npmjs.com/package/multer

“Multer is a node.js middleware for handling multipart/form-data, which is primarily used for uploading files.”

Here you will find that you can install multer like so:

Step 2: Set Up Options For Multer

So far while using Node, you’ve most likely only sent JSON data from the client and then parsed it into a javascript object. Now we will be sending ‘form-data’, taking the file and grabbing it’s binary data and sending that to the server.

So in your index file (or where you have your routes) let’s import multer like so at the top of your file.

Next we have to set up some options for multer. So we’ll set ‘images’ as the destination. Just make sure you have an images folder in your src folder.

Step 3: Create A Route

Now that we have that set up we can create our post route.

We create a route like we normally would, then add upload as middleware and calling the single function with a string. This string (in our case we used ‘upload’) is going to be the key that we’re going to use in our form-data. It must match.

Now in Postman, create a new post request to the route we just set up. Set up the body to be form-data. And then add ‘upload’ as a key. Change the type from text to file and choose an image to upload.

If you submit this you should get a status 200 and the image should be in the images folder.

If you add .jpg to the end of this newly created file you will be able to see the photo in your IDE.

Later in this article we will store the image as Binary data to a model. But for now at least we have multer working.

Step 4: Set up Validations to Restrict Size, File Type Etc.

Check out the multer documentation for more info on validations if there are any other that you want to toy with. For now we will restrict the file size and file type by adding to the multer options object.

You can add this to the multer options to limit the filesize to 1 megabyte. Since this field is in bytes, 1 million bytes is a megabyte.

Now to restrict the file type we can use the fileFilter function provided by multer.

The if statement here gets the filename on the users computer and then uses regex to check if it ends with png, jpg, or jpeg. You can make this a simple if condition using .endsWith instead if you prefer.

The callback called ‘cb’ is used to tell multer to either throw an error or continue. The first use will throw an error if the filetype is not an image. The second call will allow it through; letting the file be uploaded.

Step 5: Handle Errors

Just provide a final callback with the correct call signature (4 parameters) like so:

That will show node that this is an error callback.

Now instead of uploading the file as an image to an images folder, we will save it as a binary or ‘Buffer’ and associate it with a record in the database. And then create a route that allows us to view the image from the client.

Step 6: Associate Image With A Record

First, add a field to the model you want the image to be associated with and set it to type buffer.

Now remove the ‘dest’ property from our multer options. So now instead of going to a folder, it will do something differently. It will pass the data to the callback function on req.file. So we can access the buffer with req.file.buffer and save it as the image property on our instance.

I should mention that you need to provide the id of the record that you’re looking to add the image to.

All you do is save that buffer to the image property and it will be stored as binary.

I would change up any ‘get’ routes you have to exclude the image property, as it will be a long list of numbers that no user needs to see. (You can do this by providing a second argument to mongooses find function. An object like so {image: 0}. this will tell it to leave off the image field.)

Instead we will serve up a new route that allows the front end to use the image.

Before we do that here is the code to delete an image. It is as simple as making the image property undefined.

Step 7: Serve Up the Image for the Frontend to Use

Here we will set up a route that the frontend can access to have access to.

This will find the record, check if there is an image on it, and if so set the content type to png and serve it up.

Now if you throw this route into your browser it will show you the image that you uploaded.

Step 8: (Optional) Use ‘Sharp’ to Crop and Change File Type

First ‘npm i sharp’.

Next require it in the file.

Now instead of just setting the buffer. We use Sharp to change it in any way we want. So in this case we change our file to a png and resize it to 500 x 500. Check the Sharp docs for more options.

And that’s really it. Not too bad. If you have any questions please reach out!

If you found this helpful please consider supporting me by purchasing my strategy card game! That’s right software developers can have cool side hustles too! Launched on Kickstarter in 2020. Click here for more info:

ArmsAndInfluence.com

Thank you for reading and please follow me on Twitter @thedrewprint and find me on LinkedIn — Andrew Richards.

The Startup

Get smarter at building your thing. Join The Startup’s +724K followers.

Andrew Richards

Written by

Software Developer — Game Creator — Let’s work together! Reach out on LinkedIn or Twitter @thedrewprint

The Startup

Get smarter at building your thing. Follow to join The Startup’s +8 million monthly readers & +724K followers.

Andrew Richards

Written by

Software Developer — Game Creator — Let’s work together! Reach out on LinkedIn or Twitter @thedrewprint

The Startup

Get smarter at building your thing. Follow to join The Startup’s +8 million monthly readers & +724K followers.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store