- [Instructor] In this video,
we will instantiate the previously created class
and create the middleware that utilizes it
to handle our uploads.
First, we need to make an instance of this class
available in our routes,
and they are already built in a way
that they can accept arguments passed on
from other parts of the application.
We can start in server,
app.js,
and there, right after the feedback service on line 13,
I now add const AvatarService
equals require
services/AvatarService.
Then, a little bit further down,
I will now add to line 19
const avatars
equals new
AvatarService,
and we pass in the path
where we want to store the images
and its config
data
avatars.
Why can we do that?
Because the sample project already has this set.
In the config file,
there is already a path for the avatars defined,
and this points to data, avatars,
so all images will be stored in this directory.
Next, we have to pass avatars down our routing chain,
so I'm scrolling down
until we have this app.use here,
and here, I'm simply passing in avatars.
Next, we have to head into
the users route
here in routes, users, Index.js.
I will now, first, for the module exports here,
add
params as argument,
and then I will use ES6 destructuring
to
fetch
avatars out of the params
that have been passed down the chain.
Now, I want to create a middleware
that can work with this service class,
so I head over to middlewares.js,
and there I now add
module.exports.handleAvatar.
This function should now
accept the service class as argument,
and then return a middleware
that utilizes this service class.
This is done like that.
So we
accept avatars as argument,
and
then we return
a middleware request, response,
next,
and this middleware will now check
if there even was a file uploaded.
This means it has to run
after the multer upload took place,
so I'm adding
if
not request
file,
return next,
because we don't have anything to do here.
There is no image.
Then, we want to check if the filename
that was uploaded is valid,
so I add
if req.file,
and the metadata we are looking for is the mimetype,
which is the image type in this case,
and if it's not
image/png,
and if it's also not
image/
jpeg,
then we want to return an error,
return next,
new error,
which says
file
format
is not
supported.
But, if we have a valid image,
we will now
await
avatars.store,
and we use the
request file
buffer
that we get from multer.
We should we store the filename
that is returned from this function now?
I want to store it in req.file
.storedFilename.
This is a very common pattern to use.
If you pass down this information down to other middlewares,
you just add it to the request object.
And, we have already a request file object
provided by multer.
If we are done here,
we will simply return next.
Now, we have to go back into the users Index.js file
with the
route
for posting to registration,
and there, after the upload middleware,
and there I add now
middlewares.
handleAvatar,
and we pass in the service class instance
as argument,
and we will get a middleware back from this function call.
Next, if there was a file uploaded,
I now want to store the filename with the user,
and for that we have to extend the model a little bit,
so I go into models, UserModel.js,
and there I want to now also
have
a new field for avatar,
and this is simply
of type String.
Okay, let's head back into the route,
and now we will implement the logic
to actually store this information.
So,
if
there is a file,
and
if we also have
a filename,
then we want to
add this information
as avatar
to the user object.
We see that in the next line,
we do the user save, so when user.avatar is set,
this will be saved into the database.
Now, also for a little bit of hygiene,
we will also extend the catch block a little bit,
because what is when maybe user.save fails,
then we would still have this orphaned file
that was uploaded in our data directory,
so if anything goes wrong,
we will now
add if
request file
and request
file.storedfilename,
then we want to delete it,
because obviously there is no user stored in the database.
And we pass in the stored filename to the delete function.
Again, I already prepared a test for that,
so I run now npx
mocha
test/server/routes
/users/index.fileupload.test.js.
We see that all the tests are green.
Next, we will look into how to serve those images.