All right.
And once we have the pack in place now let's complete the update user functionality.
And actually the first thing that I want to do is to remove this image, the Avatar one, since we need
to keep in mind that we will be uploading all of the images to a cloudinary anyway, so there's really
no point to keep them around.
And essentially in the controller we'll have the functionality.
Once we upload the image successfully to Cloudinary, essentially we will remove that temporary image.
And since I want to showcase that, of course I want to start from the scratch, then let's navigate
to the user controller.
And more specifically, we're looking for update user.
Remember, there is a req file every time we upload the image and of course we'll use some of those
values from the object.
Now before we write any lines of code, I also want to set up two imports.
One is going to be for Cloudinary.
So essentially a package we just set up.
And I'm going to call this import cloudinary.
For some reason I have a typo over here.
So from.
And then the package that I'm looking for is Cloudinary.
And after that I want to import the file system module.
However, I basically want to import the promises option.
So essentially I don't want to use the callback approach.
I just want to stick a in front of it.
So on a module there's going to be a method which allows us to remove the image just like I did manually,
but I just want to stick a weight in front of it instead of the callback approach.
Hopefully that is clear.
So in here we just want to go with promises as FS.
And then the file system module like so.
Now alternatively, you can go with forward slash and promises, but I'm going to stick with this approach.
Then let's scroll down and let's start setting up the functionality.
So first thing we want to do is to set up a check.
So essentially I only want to upload the image if the user is sending the image.
Again, please keep in mind we can update the user without updating the image.
So therefore we're going to go here with if then rec dot file.
So if it exists, then we want to do something.
Now what is that something?
Well, for starters, we're going to go here with response and we'll set it equal to await and then
we'll go with Cloudinary.
So Cloudinary package has the method upload and essentially we want to stick await in front of it.
Now not only we go with upload, but also we need to add version two.
This is very, very important.
Then uploader, then dot and then finally upload.
And then in the upload method we want to pass in the req dot file dot path.
So req file and path.
And then this is going to return an object.
If we're successful, there are some values we want to grab from there, but before we save anything
in the database, like I said, I want to remove that file, so I'm not going to do that.
Of course, manually.
I'm going to go here with Await then FS, So that's my module.
And then the method that I'm looking for is Unlink.
And in here again, same deal we want to pass in req dot file dot path.
So if I can successfully upload to cloudinary, I don't want to keep that image around.
Now as far as this response, like I said, this is going to be a giant object and in there I'm looking
for two properties, I'm looking for secure URL.
So this link will point to the image and therefore it's always going to be around.
And of course I'll use that link on the front end to display the image.
And also I want to get the public ID.
Why?
Well, because I don't want to keep the old images around and I want to remove the old image.
If the user already uploaded an image before and you'll see what I'm talking about in a second.
So remember, we have over here this object and I actually want to rename it instead of this generic
object, I'm going to call this new user.
Then in here I'll change it to new user.
And also remember here we're passing this object.
Let me rename it to new user.
Now, this is not going to affect the functionality, but at least that's going to be my approach.
So I'm creating a new user and basically we want to go here with new user dot and then remember the
property name.
It was Avatar, correct?
So I want to set it equal to response, then dot, then like I said, secure URL and the second property
I want to set up is that Avatar Public ID?
So new user and then Avatar.
Public and then ID and that one is equal to response dot and public underscore ID.
Now, once we're done with this condition, of course we still use find by ID and update.
So we still update the user.
But notice how I'm not returning the updated user.
So essentially in this updated user we have the old instance before the update.
Now why do we want to do that?
Well, like I said, imagine this scenario.
I upload the image, I use that image for one week, two weeks or whatever, and then I decide that
I'm going to upload a new file.
So we nicely remove that image right away from the local file system.
Correct.
We don't have any old images lying around, however.
With the current setup.
In the cloudinary.
I can get tons of images and most of them can be just some old images lying around.
And keep in mind, whenever you start using services like Cloudinary, they pretty much charge you for
the amount of data you're storing, the amount of data you're requesting and all that.
So we definitely don't want to keep some old images lying around.
So if the user is updating the image, we want to remove the old one.
And therefore in here I'm returning the old instance because I want to access that public ID since the
Cloudinary package in order to remove it, is looking for that value.
Now again, please keep in mind that I only want to do that if the user is sending the image.
Since again, if the user is just trying to change the name, of course I don't want to do that and
therefore I'm going to set up another condition.
I'll say, listen, if the rec dot file is present, then I want to actually remove the old one.
But I also want to check whether there is an existing image on the cloudinary because please keep in
mind that the first time we register the user, of course we were not providing the image.
So the first time the user is uploading the image, there's not going to be that old public ID.
Basically it's just going to be an empty string.
So therefore in here, I want to also check whether there is an old image and I can check that since
I'm returning the old instance and I'm just going to go with updated user.
And if you want, of course you can call this old user maybe if that makes more sense to you.
And then I want to go with public ID, So if there's a new file and if there is an old one in the cloudinary,
then I want to proceed.
And essentially I just want to go here with Await.
Then again, Cloudinary package version two super, super important, then uploader, then the method
is destroying this case and like I said, it's looking for the updated user dot avatar and public ID,
so it's looking for.
That string value.
And once we are done with the server, now we quickly want to swing back to the client.
We're looking for source more specifically components.
And then somewhere here there should be a logout container.
And remember when we were setting up the button, I said that eventually we'll have a condition for
the circle.
So like I keep saying, initially when we register the user, there's not going to be the image.
We're only going to have image if, let's say, user navigates to a profile and then uploads the image.
That was my setup for this application.
So in here I want to set up a condition where if the avatar is present, then I actually want to use
that avatar property.
Now, if there is no avatar, then I'm going to go with the circle.
So let me showcase.
I'm going to go here with user object.
Avatar.
And then I'll set up the ternary operator and I'll say, Hey, listen, if it's actually present, I'm
going to go with image source.
Now, the good news is we already set up the.
CSS for it.
And as far as the source is going to be dynamic, I'm going to use again that.
String value.
So user avatar.
Then let's add also the alternative.
I'm just going to go with Avatar and then let's not forget about the class name.
And this is equal to an image.
I want to close my image.
And if the Avatar property is not present, then of course we'll just showcase the circle.
So now let's navigate to the browser and let's basically test it out.
I'll start everything from scratch over here, so let me log out then register.
You know what?
I'm going to go with Susan.
So Susan Smith.
And also we want to go, of course, with unique.
Email.
Let's save.
So this, of course, is going to be equal to Susan.
Okay, let's log in.
We should have no jobs.
That's totally fine if we navigate to a profile.
Now, I want to upload the image because as you can see at the moment, we only have over here this
icon.
Correct.
So let me go with the wrong image.
Basically, let me go with Avatar one, just to showcase that that value is not going to be stored in
the cloudinary.
I'm talking about the old one.
So let me just update, of course, this one over here and.
Notice successful.
And now I can actually see the image over here.
Now it's the wrong image, but we're moving in the right direction.
And again, before we actually check the cloudinary, I just want to emphasize something.
If I'm going to go here with just a last name, of course everything is going to be fine.
Correct.
So we don't need to send the image each and every time we are updating the user.
So now let's navigate to a cloudinary.
I probably need to refresh.
And then I'm looking for media.
And check it out.
So this is going to be my image, correct?
That's the image I just uploaded.
And again, the main reason why we had such extensive functionality in the update user is because I
don't want to keep this old image if the user decides to change the image.
Actually, before we update the image, I also want to stress something that we're not keeping those
images around.
So notice how the uploads is actually empty, but we have the image on cloud nine.
So now let me navigate here.
And pick the right avatar.
So I want to pick this image.
And let me send it.
And notice I successfully changed the image profile was updated successfully.
And if we navigate here and if we refresh notice, only the latest image is stored in the cloud, which
is obviously super, super awesome.
And with this in place, we're done with update user functionality.