Welcome back guys to part 5 in this series of writing our own Twitter clone using express on node. Last week we add the functionality for a user to edit their profile information and we also added a few visual elements. This week we are going to add more functionality and give the user the ability to change their header image and profile image in our edit user menu. Let’s get started!
Lets take a look at how Twitter implements this, it’s actually quite cool: when a user decided to edit their information their header image and profile image get this sort of overlay tell them they can change it, then when the user clicks it asks if they want to change it or remove it completely. Here is what is looks like:
We are going to mimic this functionality however instead of giving the user the option to remove it or change it we will just allow change. The change will happen as soon as the user new upload is finished and the new image will be shown immediately while still saying inside the edit user information menu so the user can continue editing.
First question we are going to ask ourselves is how are we going to store the images? Since they need to be associated with the user my first tuaght was to store them in the user table in Mongo. After reading up on it, it is widely said that storing them directly in Mongo is not a good idea. There has been a node module made for this purpose it’s called gridfs but I taught it was a bit much for our little project. What we are going to do is we are going to store the images locally and store the actual image location in the database.
So if the user uploads their header photo it would be stored in public/img/imageName.png and that string would be stored in the user table.
So let’s get started with the code:
As you see we have added two columns for the user header image and their profile picture location.
Now we have our database schema object setup let’s add our route code that is going to execute when they upload a header image and profile image:
Header image route:
Profile image route:
In both of these routes we are using busboy module to check for file uploads, once we see the fileUpload field has been triggered we create the userFileLocation variable then we create a write stream so we can write the uploaded file to our directory(in public/img). We then pipe our file into the fstream and say once the file is completely uploaded, get the user that request a new upload from the database and change their header/profile img location. Once its saved to the database we return the location of their newly uploaded image so we can point to it in our html.
Now have our routes setup let’s add the forms to our profile.jade page so we can use our routes:
Header image form:
Profile image form:
As you can see we have two forms one for uploading the header image and the other for uploading a profile image. Some things you may notice:
– we have the forms hidden which we will display when the edit profile info is clicked
– we have a our file input code in a label this is so we can customize it to the way we want, E.g just having an image that when clicked bring up the file dialog.
– keen eyes people might say wait you have a form without a submit button…how are you going to submit the data? Well keen eyed people we are going to use Ajax to submit our form as soon as the image is uploaded and display their new profile/header image right away. All that is done without any page reloads…I am starting to like Ajax!
Right we have setup our HTML and server side code now all that is left is the styling for the custom file inputs and our js with our Ajax call.
Ajax call to upload a new header image:
Ajax call to upload a new profile image:
As you can see we have two Ajax calls that look very similar as they both basically do the same thing but they are POSTing to different routes, one for headerImage update and one for profileImage update. We are reading the file the user uploading and getting it ready so we can submit it via an Ajax call. If the call is successful we are getting the callback data from node which as you can see from our route code it will be the path to the users new image.
We are then setting the background of the header image/profile image to the users new image via jquery.
Here is the result:
Woo so we are done we have given the ability to the user to be able to change their profile image and header image all within the same menu as they would use to change their other information. I hope you enjoyed the tutorial I really leaned a lot about file inputs and using Ajax/jQuery to reload certain parts of the page. Next week we are going to try to finish up the profile page by adding some last touches so see you guys then.