Okay, so now we can create and edit products, but we can only edit the text fields.
We want to be able to upload the image as well.
So we're going to use a package called Malter for this, which is pretty popular.
You can see it has 4 million weekly downloads.
It's basically the go to for NodeJS and uploading images and you can use different sources.
For instance, if you wanted to use like Amazon's buckets, S3 buckets, you could do that, but we're
just going to upload directly to the server.
Okay?
So we need to install it.
And then basically we need to just add some middleware and hook it up.
And everything we're doing is pretty much in this documentation.
I just I don't really like how the docs are set up here, at least on the GitHub page and the NPM page
because it's all so spread out.
So it's kind of hard to figure out exactly what to do.
But that's what I'm here for.
So we're going to install this now.
Make sure you install Multer on your back end, meaning your in your root, not in the front end.
So I'm going to stop the server and I'm in the root directory right now and we're going to NPM install
malter.
Again, make sure you're not in your front end.
So then we can just run the server again.
And we're going to go into our back end.
First thing we're going to do is create a new route.
So we're actually going to create a new route file.
So in routes, let's create a new file here called Upload.
Routes.
Uh, routes dot JS.
Okay.
And then we're going to bring in a couple things here.
So I want to bring in the path module so we can use that.
So install path import path from path.
And then I'm also going to bring in Express because we need the router.
So let's say we'll import Malta first and then create the router.
So const.
Router equals express router.
And then before I forget, I just want to export as default router because sometimes I forget to do
that.
Now, before we even create our routes, we need to describe where we want our image to go, which storage
we want to use.
So we could use Amazon buckets or disk storage, which is what I want.
So let's say const storage and set that to multer dot disk storage because we want it to just be on
the disk on the server, right?
And then this takes in an object with a couple functions.
First is going to be destination.
So this will describe where we want to save this and notice that we pass in request file and CB So CB
is the callback that we want to call within here and the null.
The first argument of null pertains to an error which we don't have an error, so we're going to put
Null for that.
And then the second is where we actually want our uploads to go, which is going to be in a folder called
uploads and this is in the route.
So what you want to do is in the route here, create a folder called uploads, don't put it in the back
end folder or front end folder, just put it right in the route.
Okay.
And any images that get uploaded through our app will go into here.
Now we're going to put a comma and then we want a file name function because we need to describe how
we want our files to be, our file names to be formatted.
So we're going to go ahead and call the callback pass in Null for the error.
And then this is how we're going to create our file names.
So it's going to be the field name, which can be anything really.
We're just going to use image and then Dash and then whatever the timestamp is with date dot now and
then we'll use whatever extension the file has, which could be Jpeg, PNG.
We're actually going to have some validation so that we can only have image files, but it will use
the extension name.
That's what this ext name does of the original file.
All right now.
That should do it as far as this storage variable goes.
Now we want to create a function to check the file type because again, we don't want people to be able
to upload like PDFs or X files or anything like that.
So for now, let's.
I think this is what we want.
So we're going to have a variable called file types.
This is just a regular expression of what we want to allow, and I want it to allow JPEGs, Jpeg and
PNG, and then we'll have our extension name, set that to file types, which is this variable dot test.
And then we're going to pass in the extension of the original file name and make it all lowercase.
And then for the mime type, we're going to pass in just file dot mime type.
All these properties are available on this this file object, and then we're just going to check the
extension name and the mime type and test is just to do just that test to see if it's going to match
our regular expression.
And then if it does, we're going to return the callback with true as the second argument else, we're
going to return the callback with an error.
Because remember, the first argument is your error.
So here we actually want an error and we're going to say image is only.
All right.
Now to do the actual upload, let's.
Come down here and we're going to say const upload equals malter.
And in this object we're going to pass in our storage variable.
Now we can create the actual route.
So let's say route router dot post.
And do that.
So this middle part here, this is the middle where we're using and we're using single because we only
want to allow a single file.
You can make it so that you can upload multiple files as an array.
It's a little more advanced, but you can do that.
But in this case, we're only using a single image and I'm calling it image.
But you could use anything here, but this is the field name.
So back up here.
When I say file dot, field name, it's going to be whatever I put here.
So in this route, we're just going to send a response dot send because the actual upload is handled
by the middleware by this.
So we don't have to do much here.
We just want to just send back something.
So we'll send an object and we'll say message.
And say image uploaded, and then we'll send the image path which we can get from the request object
here.
It'll have a file object which will have a path.
And that should do it.
Now, just like we did with the rest of our routes, we have to go into our server.js.
So let's go into back end server.js just like we did with these three.
We have to bring in our upload routes.
So let's say import.
Uh, upload.
Routes from our upload routes and then just add that down here.
So we'll say app dot use and it's going to be slash API slash upload and we want to connect that to
our upload routes.
Now the upload folder that we created, we want to we want to make that static, right?
We want to be able to just access that.
So let's put this first of all, let's bring in our path module because we need to use that.
So I'm going to say import path from path.
And the reason I put it at the top is because if I use a built in module like Path or FS or URL or Http
just built in node modules, I always put those at the top.
I think it's a good convention.
Now we just want to set that uploads folder as as a static folder.
So I'm going to come down here and we're going to say const double underscore Dirname.
And set that to path resolve.
So this is just setting this double underscore dirname to the current directory.
And then we want to just app dot use and pass in uploads.
So the file path is the first first argument.
Then we're going to make it static by saying express dot static and then passing in the location of
that folder and we're just using Path.join to do that.
All right, so we'll save that and then we should be all set as far as our back end.
So in the front end, we're going to add.
In our edit screen here, we're going to add an image field and then we'll be able to select an image
and then submit it to this route.
So we'll do that next.