In this video you're going to learn how to create a link between the image uploaded and the user who
actually uploaded it.
Right now all of the Avatar pictures are being dumped into a directory and there's no link between the
user who created it and the image that was uploaded.
This route isn't even behind authentication so those are all things we want to fix.
We'll start by putting the route behind authentication and then we'll create a place on the User model
for the image data to be stored.
And finally we'll be creating a separate route that authenticated users can use to delete a profile
picture they've set.
So let's go ahead and talk about how we're gonna get all of this done.
Step one is to set up authentication.
Adding authentication is gonna be just as simple as it's been for all of the other routes we've worked
with.
Now the only difference is that this route already has one piece of middleware in place that is melter.
All we're going to do is add our authentication middleware before.
So we want to make sure they're authenticated before we worry about accepting their upload because if
they're not authenticated we would never accept the upload.
So right here that is off followed by a comma.
So now we are passing multiple arguments to post.
We have first the path then we make sure they're authenticated.
Then we go ahead and validate and accept the upload.
Right here we send back the success message and down below we handle any errors that might occur when
the upload was processed.
So this is step number one the next step is to figure out where exactly we're going to store that image.
We're actually not going to store it on the file system for the project like we've been doing so far.
The reasoning behind this is that almost all deployment platforms require you to take your code and
push it up to the repository on their servers.
We saw this with Heroku and the same would be true if you were using something like a W us.
So the file system actually gets wiped every time you deploy which means that we would lose data when
we deployed we would lose those user images.
So instead of storing them on the file system we're actually going to add a field onto the User model
to store the image of binary data.
That means we're going to make a very small change to the user model over here after tokens or before
the order doesn't matter.
We're gonna be setting up a new field which we can call Avatar and we're only going to configure this
with a type.
So right here the type is going to be capital B buffer.
This is going to allow us to store the buffer with our binary image data right in the database alongside
of the user who the image belongs to.
Now we don't need to make this required as we're not going to make profile pictures required.
They'll be completely optional and there's no need to perform any validation send smelter already takes
care of that for us.
This is actually the only change we need to make to the user model so we can go ahead and save this
file and figure out how we're actually going to get access to the data over here.
Now what would be ideal is the ability to actually access the binary data right here we would update
the user profile and use that save method we've used to so many times before to save these changes to
the database.
The problem is that our root handler.
This function.
Right here it does not get access to the file data that was uploaded.
That's because Mulder runs first and it processes the image saving the image to the avatars directory.
Now Malta does give us a way to actually access the data inside of here and all we need to do to get
that done is remove the dest property from our options object up above.
When we do this the multicore library is no longer going to save images to the avatars directory.
Instead it's simply going to pass that data through to our function so we can do something with it.
We could save it to the file system if we wanted to.
But in this case we don't.
We want to save it on the user profile.
So now we're still going to have Malta processed the image data and validate it as we've set up above
but it will pass the validated data through to our callback function so we can access it.
The data is accessible on request dot file.
This is an object which contains all of those properties we explored before about the file and we're
gonna be using one called buffer buffer contains a buffer of all of the binary data for that file.
And this is exactly what we want access to.
So this is something that once again we can only access in our handler when we don't have that dest
option setup.
The next thing we're going to do is actually take this value and store it on the user avid char field.
So over here.
Request dot user dot Avatar is going to equal whatever is on request dot file dot buffer.
And the last thing we need to do is save the user profile since we've just made a change to it.
So I'll use a wait with request dot user dot save like we've done plenty of times before.
Now if I do want to take advantage of a way all I need to do is make sure I am working in an async function.
I'm currently not but I can add a sync up front of the arrow function definition to change that.
So at this point motor is processing the data passing it through to our function or storing the file
data on the avatar field and saving it.
And what I'd like to do from here is actually test our work and make sure it's working as expected.
What I'm going to do is save this file and try to upload a new avatar over inside of post man.
I already have my upload Avatar request and I'm uploading the data correctly like we were doing earlier
and I'm already authenticated because I've created this request in the task app collection and under
authorization it's inheriting it from the parent which we set up a few sections ago.
That means all I need to do is actually send this off to have the data added on to the user profile.
Now when it comes to what we send back from this request it doesn't really make much sense to send anything
back.
Though you could if you wanted to in this case we can send back an empty body with the 200 status code
so they know that things went well.
Now at this point I would expect to see an avatar field on the user in the database.
What I'm gonna do is head over to robo 3D for the first time in a little while and I'll refresh the
user's collection.
I have a single user and if I crack them open down near the bottom what do I have.
I have that Avatar field with my binary data right here.
Now for the moment we're not going to worry about creating a route to actually serve this image up.
That's something we'll focus on in the next lesson for the moment.
What we can do is just copy this binary data to the clipboard and write a little H2 UML in the browser
so you can see what it would take to render the image.
What I'm going to do is right click my document and click edit document and what we're looking for here
is the Avatar binary data.
Now down below we have Avatar when we use the buffer type.
It's actually set to an object and the dollar sign binary property that's what contains our data.
So I need everything starting right here to the very end of this quote.
So what I'm gonna do is highlight a part of it then using the scroll bar I'll go all the way to the
bottom and I will shift click right at the end just before that closing quote to highlight everything.
I'm gonna copy it to the clipboard and that is the binary image data.
Now we can go ahead and click cancel to close down the editor and we're gonna move into the browser
for just a moment.
We're gonna go over to one of those Web sites that allow you to write a little bit of markup and then
see it.
We have things like code pen J.S. bean code sandbox and dozens of others.
I'm gonna use J.S. bean which is just the tool I've used the most.
Now right here by default we see HDL javascript end of the rendered output.
We're gonna go ahead and close down the javascript tab as we're not going to need it.
We need to do is be able to write some HDL like an h1 tag and see it rendered over here.
Now what we're gonna do is setup an image tag and render an image based just off of our binary data
for the image we have to set the source attribute.
Now typically this would be a you are out a path to where the image lives in the browser would fetch
it and render it to the screen.
We can also though provide binary data right here to render the image without needing to make that extra
request right here to get that done.
We first start by specifying what exactly we're providing.
It's not a U.R.L. it's data.
So that is data.
Colon followed by the type of data.
In this case it is image forward slash JP G.
If it was a PSG it would be image forward slash PSG.
Next up after a semicolon it is the encoding our data is Base64 encoded which just removes special characters
that typically cause problems with things like you are ls.
Then after a comma what do we provide.
This is where we provide our binary data.
So this prefix makes sure the browser knows how to render the data we're providing it.
Then we simply paste in that data.
Now over here on the right hand side we have a grey box.
That's just because our image is really really big.
But if I scroll around we can indeed find the profile picture.
Our robots face.
So using our binary data we can render images in the browser by just specifying that you are well structure
like this.
This is one way we can show those profile pictures.
We request the user's profile.
We grab the avatar data and we dump it into an image element.
Now that we've seen this we're going to wrap up the video with a challenge where you're going to set
up a route for deleting that data from the user profile in the next video we'll talk about how we can
create a U.R.L. to serve those images up.
But for now let's go ahead and talk about what I'd like you to do for the challenge and I'll paste the
challenge comments right here down below right here.
Your goal is to set up a route allowing someone to delete the avatar they've previously uploaded.
You're gonna start by setting up the route delete forward slash users forward slash me forward slash
avatar.
So essentially it's the same request structure up above but we're swapping out post for delete and you're
also going to add authentication as we need to know which user we are deleting the avatar for and the
actual root handler.
All you have to do is set the correct field to undefined to save the user document to wipe that data.
And finally send back something like a two hundred.
There's no need to send back an actual response body.
The status code is enough.
Last up test your work.
Create the new request for the task app collection in post man.
Fire it off for the user and then check the data in the database.
They should no longer have that Avatar field showing up.
Pause the video.
Knock this out.
You can add the new route right here when you're done and come back and click play.
How'd that go.
Let's go ahead and get started by calling a router.
Dot delete to set up the root entity you are L is forward slash users forward slash me a forward slash
avatar as we are deleting the avatar for ourselves.
Next up we do on authentication so I'll add that in right now followed by our function.
I plan on using a wait inside of there so I'll set it up as an async function and from inside of here
the goal is to start by wiping the avatar field on a user so request dot user dot right here.
Avatar will get set equal to undefined when we wanted to save a profile picture.
We set that field when I want to delete it.
I clear that field.
Next up we have to make sure to save that user profile.
So I will await a call to request dot user dot save.
And next up we can go ahead and use response dot send to send back a two hundred request.
Now from here we have knocked out steps 1 2 and 3.
The last thing we need to do is to test our work and make sure this actually functions correctly.
I'm going to go ahead and remove the challenge comments I'll make sure to save the user router and we're
going to head over to postmen and give this a try.
So I have to create the new request which I will do by adding it to the task app collection I can call
this whatever I'd like.
I'll go ahead and call it something like delete.
Avatar I'm going to create it.
Down below it shows up I'll crack that open and customize it to fit my needs.
This does indeed use delete and the structure starts with you are L stored in the environment variable
followed by a forward slash user's forward slash me forward slash avatar.
Now authorization is already set up right here in this tab.
So we're good to go.
We can actually fire that request off.
I'm going to send this off using post man.
I get a two hundred back and we can verify it actually worked by looking at the database over in robo
3 T.
I have my avatar I use it command R to refresh it.
I cracked that open again and now the avatar is gone which is fantastic.
So now when we are uploading avatars those are getting uploaded and saved as part of the user profile.
And we've also provided a user with the ability to delete their profile picture if they don't want it
anymore.
Now if I simply wanted to change my profile picture I could just use this request again to actually
get that done.
So if I was creating a front end application for this task app this route right here would be used for
creating an avatar and for updating it and the one below would be used for just wiping it.
There's no need to wipe before saving.
Now that we have this in place we are all done for this lesson in the next video we're going to explore
some of the ways we can serve up this image data so it can actually be accessed and used by our client.
I'm excited to get to that.
So let's jump right in to the next one.