WEBVTT 0 00:00.930 --> 00:07.680 Now in the last lesson we looked at how we can run code inside our EJS templates. 1 00:07.680 --> 00:13.460 Now in this lesson I want to continue building out the functionality of what is our main goal right? 2 00:13.500 --> 00:15.670 Making a To Do list app. 3 00:15.810 --> 00:22.080 So inside our App.js wouldn't it be great if we didn't have to use this massive Switch statement to 4 00:22.080 --> 00:30.600 convert this day from 0, 1, 2, 3 into the actual name say Sunday, Monday, Tuesday. Wouldn't it be great if we could 5 00:30.600 --> 00:32.700 just use Javascript to do that? 6 00:32.700 --> 00:34.870 Well let's see if it's possible. 7 00:34.890 --> 00:43.140 So if you go into Google and we search for something for example Javascript date format, then if you 8 00:43.140 --> 00:49.710 take a look at this highly relevant Stack Overflow post which says, 'How can I format a Javascript date 9 00:50.010 --> 00:52.570 to print in a specific way' 10 00:52.800 --> 00:57.570 then you can see that there's a whole bunch of answers and the accepted answer actually has this part 11 00:57.570 --> 01:00.180 where it says this answer was written in 2010. 12 01:00.210 --> 01:04.710 And there's better answers below and that better answer is actually this one. 13 01:04.810 --> 01:12.690 There's a method called toLocaleDateString that allows you to format your Javascript using whichever 14 01:12.690 --> 01:14.520 format you wish. 15 01:14.730 --> 01:20.120 So for example you can include a day as numeric or 2-digit, 16 01:20.520 --> 01:26.560 then you can have a weekday day which which can be narrow, short or long. 17 01:26.890 --> 01:29.290 And you can have it for different languages. 18 01:29.340 --> 01:36.210 So if you take a look at their example, they've created this variable called options which has a number 19 01:36.270 --> 01:37.520 of properties. 20 01:37.680 --> 01:39.850 So weekday is set as long, 21 01:40.000 --> 01:49.260 year is set as numeric, month is long, day is numeric then they've created a new date and they've called 22 01:49.320 --> 01:58.650 this method on that date rendering it in a US English format which looks like this without the options 23 01:58.800 --> 02:00.830 and with the options included 24 02:00.990 --> 02:03.750 it looks like this. 25 02:03.780 --> 02:06.880 So this is pretty much what we want. 26 02:07.200 --> 02:11.110 And so we're going to borrow this and add it to our code. 27 02:11.310 --> 02:14.610 So firstly we have to create our options, 28 02:15.240 --> 02:17.880 and this is going to be a Javascript object. 29 02:18.000 --> 02:23.490 And in our date I want to have a weekday to begin with. 30 02:25.840 --> 02:30.600 And my weekday, the option I'm going to set is going to be long. 31 02:30.640 --> 02:36.640 I want to write out the entire day of the week. Weekday which is going to be long and the next thing 32 02:36.820 --> 02:46.360 is the day which is going to be numeric and finally we're going to add that month which is going to 33 02:46.360 --> 02:48.040 be long as well. 34 02:48.370 --> 02:51.550 So now we have our options object. 35 02:51.550 --> 02:55.550 We're going to use it to render our date. 36 02:55.740 --> 02:58.360 So let's create a var day. 37 02:58.640 --> 03:07.930 And this is going to be equal to today.toLocaleDateString and you can see that this converts 38 03:07.990 --> 03:15.430 a date to a string returning the date portion using the operating systems locales conventions and of 39 03:15.430 --> 03:22.020 course that means that you have to add in the locale which is basically a region. 40 03:22.180 --> 03:25.640 And we're going to use something like English US, 41 03:25.960 --> 03:31.960 so en-US and if you want that date string to be rendered in Japanese or Chinese, then you can 42 03:31.960 --> 03:34.330 change that to the relevant locale. 43 03:34.510 --> 03:41.350 So en-US and then we're going to pass in our options to format that date string. 44 03:41.650 --> 03:49.650 So now if we hit save then this formatted day gets passed in here which gets sent over to our list. 45 03:49.910 --> 03:53.610 ejs as a variable called kindOfDay. 46 03:53.820 --> 03:56.790 And now to clear this part up as well 47 03:56.830 --> 04:02.830 instead of having this code that checks for the kind of day, I'm going to have a really simple h1 that 48 04:02.830 --> 04:07.600 just logs that date string inside an h1. 49 04:07.810 --> 04:12.050 So I'm just going to put kindOfDay inside this tag. 50 04:12.070 --> 04:16.670 So now if we hit refresh then you can see that we get our formatted string 51 04:16.690 --> 04:19.180 Thursday June the 7th. 52 04:19.540 --> 04:26.440 And now that we've tidied up our code a little bit, we can get on with building out the rest of our 53 04:26.440 --> 04:27.390 to do list. 54 04:27.520 --> 04:34.400 So the simplest form of our to do list is simply an unordered list with a bunch of list items. 55 04:34.480 --> 04:40.280 So this will generate us a bunch of bullet points with each of our to do list items. 56 04:40.390 --> 04:43.390 So first one will be buy food, 57 04:43.450 --> 04:44.900 then you have one called-- 58 04:44.920 --> 04:47.490 then of course you have to cook the food. 59 04:47.560 --> 04:52.750 And my favorite part which is eat the food. 60 04:52.750 --> 04:54.660 Now look at the clock 61 04:54.670 --> 04:56.500 it's almost lunchtime. 62 04:56.500 --> 05:01.530 And guess what I'm thinking about? 63 05:01.580 --> 05:08.620 So this if we hit save will render a web page as a bunch of bullet points. 64 05:08.620 --> 05:17.950 So now we want to be up to add new items to this list and in order to do that, we need to pass data back 65 05:18.370 --> 05:28.070 from our web page to our server. And how have we been doing that so far? Post requests of course. 66 05:28.480 --> 05:37.600 So as a challenge I want you to create a new form inside your list.ejs just as you have been doing 67 05:37.600 --> 05:40.250 before inside your index.htmls. 68 05:40.630 --> 05:48.190 And this form is going to have a single text input that is going to take whatever value the user puts 69 05:48.190 --> 05:56.050 in there as the next to do list item. And then when you hit the submit button it's going to make a post 70 05:56.050 --> 05:58.400 request to the home route. 71 05:58.570 --> 06:04.570 So to complete the first part of the challenge, I just want you to create the form that is going to make 72 06:04.570 --> 06:11.050 the post request inside our list.ejs in the same way that you have been doing it before inside your 73 06:11.080 --> 06:12.500 other HTML pages. 74 06:12.640 --> 06:15.180 So pause the video and give that a go. 75 06:17.330 --> 06:23.730 All right so we start off by creating a new form and I'm going to keep the class empty for now. 76 06:23.870 --> 06:30.650 And I'm going to change the action to our home run which is that forward slash or also known as the 77 06:30.650 --> 06:33.300 root route. But I find root route 78 06:33.350 --> 06:38.210 a bit of a tongue twister so I'm going to continue calling it the home route. But I'm sure you understand 79 06:38.210 --> 06:39.290 what I'm talking about. 80 06:39.350 --> 06:45.890 So the method I'm going to keep as post which is going to post the information that's inside my form 81 06:46.070 --> 06:49.450 to my server at the home route. 82 06:49.460 --> 06:56.810 So now inside the form we're going to add a single input that is going to have type text and the name 83 06:56.870 --> 06:58.340 of this input 84 06:58.340 --> 07:06.110 we'll just call it newItem. And I'm going to delete the value because the value is going to be whatever 85 07:06.110 --> 07:09.220 the user inputs into that textfield. 86 07:09.230 --> 07:17.150 And finally I need to add a button which has a type of a submit so that it will trigger this post request 87 07:17.240 --> 07:23.690 in the form to this route and the name I'm going to keep as button but the button is going to have 88 07:23.690 --> 07:25.380 a title of add. 89 07:25.700 --> 07:33.260 So now if we hit save and we refresh our page we've now got an input where I can put in anything I want 90 07:33.650 --> 07:40.010 and when I press add of course nothing happens. And we get this error saying, 'Cannot POST' to the home 91 07:40.010 --> 07:40.610 route. 92 07:41.030 --> 07:47.620 And that is because we have yet to write the code in our server to handle that post request. 93 07:47.690 --> 07:49.470 So you know what's coming, 94 07:49.520 --> 07:51.200 there's another challenge. 95 07:51.200 --> 07:59.420 So inside your App.js, I want you to write some code that handles the post request to the home route 96 08:00.050 --> 08:05.610 and just console log the text that the user wrote into that input. 97 08:05.660 --> 08:12.130 So pause the video and see if you can complete this challenge. All right. 98 08:12.130 --> 08:21.190 So as always we start off by writing app.post to handle post requests that go to a particular route. 99 08:21.550 --> 08:21.990 And the route 100 08:22.000 --> 08:25.650 in this case that we want to handle is the one to the home route. 101 08:25.960 --> 08:32.740 And when that does happen, we're going to trigger a callback with a request and a response. 102 08:32.890 --> 08:41.270 And inside our callback we're going to grab the value of what's inside our text box. 103 08:41.320 --> 08:47.710 So remember we gave our text box a name of newItem and that's equivalent to the name of a variable. 104 08:47.890 --> 08:57.600 And we can tap into that value by tapping into request.body.newItem. 105 08:58.240 --> 09:05.120 But before we can use this thing called body, we of course have to set up body-parser. 106 09:05.320 --> 09:07.690 Now you can write this anywhere below where 107 09:07.720 --> 09:11.590 we create our app, but I'm just going to add it between the set and the get. 108 09:11.590 --> 09:19.540 So I'm going to say app.use bodyParser.urlencoded. 109 09:19.540 --> 09:25.540 And we're going to set the extended option as true. 110 09:25.840 --> 09:29.080 Now it doesn't really matter if you set it as true or false 111 09:29.080 --> 09:32.200 in our case but you do have to give it a value. 112 09:32.320 --> 09:39.280 So now that we've told our app to use bodyParser, we can now grab the value of new item using this line 113 09:39.280 --> 09:47.510 request.body.newItem. So we can either save this into a variable called item and then console log 114 09:47.510 --> 09:53.970 it, or you can of course simply place this inside here and remove the need for that extra line. 115 09:54.190 --> 10:02.200 So let's just review what happens when we press the submit button. Our form is going to make a post request 116 10:02.350 --> 10:11.290 to the home route and it's going to post the value of our text input which has a name of newItem. 117 10:11.290 --> 10:19.710 Now when that request is received, it gets caught inside this app.post section. And we tap into the 118 10:19.710 --> 10:20.470 request 119 10:20.530 --> 10:27.300 looking through the body of the post request and we search for the value of something called newItem. 120 10:27.340 --> 10:34.930 So this has to match up with the name of our input in order to retrieve the value of that text input. 121 10:35.170 --> 10:37.230 And then we log the value of item. 122 10:37.240 --> 10:45.010 So let's hit save and let's try and give it a go. Go back to localhost:3000 and let's add a 123 10:45.280 --> 10:47.840 new item, press add. 124 10:48.070 --> 10:55.900 And now if we go into our hyperterminal you can see that the value of that text input gets logged inside 125 10:55.900 --> 10:57.440 our console. 126 10:57.490 --> 10:58.330 So brilliant. 127 10:58.390 --> 11:00.490 That's now working. 128 11:00.490 --> 11:03.290 So onto the next thing that we need to do. 129 11:03.430 --> 11:13.630 So we've now passed the data from our web page to our server but we now need to pass the data back into 130 11:13.710 --> 11:21.850 our web page namely into a new list item inside the ul. So we can start doing that by creating a new 131 11:21.850 --> 11:30.480 list item and its content is going to be a EJS tag that is going to render a new list item. 132 11:30.490 --> 11:34.750 So now we just have to pass in that new list item. 133 11:34.870 --> 11:39.550 Now some of you might think that you could do it inside the post request. 134 11:39.730 --> 11:48.880 So for example you could say res.render just as we did up here and we render our list template and 135 11:48.880 --> 11:50.890 we pass in our item. 136 11:50.890 --> 11:55.470 So remember the variable name was called newListItem 137 11:55.480 --> 12:01.630 so I'm just going to copy it and put it in here as the key. And then the value is going to be equal to the 138 12:01.630 --> 12:03.850 value of our variable item. 139 12:03.850 --> 12:07.030 So I'm just going to write that inside here. 140 12:07.690 --> 12:12.580 So we're going to render the list template and we're going to pass in this. 141 12:12.610 --> 12:18.820 Now there's a bit of a problem here because right now if you save everything, you save the App.js and 142 12:18.820 --> 12:26.650 your list.js and you try to refresh this page you will get a error. And it tells you that inside 143 12:26.650 --> 12:29.700 your list.ejs on line 17 144 12:29.740 --> 12:37.200 there is a problem. And line 17 is where we are trying to render our newListItem. 145 12:37.300 --> 12:41.450 And the problem is a newListItem is not defined. 146 12:41.470 --> 12:48.730 This is because when we try to go to localhost:3000 i.e. our home route, then we land inside this block 147 12:48.730 --> 12:55.330 of code. And you can see that when we're trying to render list we're only passing in the value for this 148 12:55.390 --> 13:00.770 variable kindOfDay and we're not passing in anything for newListItem. 149 13:00.970 --> 13:10.120 So when it tries to render a list at this point then it doesn't actually have a value to put into this 150 13:10.270 --> 13:13.240 new list item EJS tag. 151 13:13.840 --> 13:16.630 And that is why our app crashes. 152 13:16.840 --> 13:26.800 So we now know that every single time you try to render a list we have to provide both variables that 153 13:26.830 --> 13:28.830 we want to render. 154 13:28.840 --> 13:37.510 So to fix this then we would probably want to add our newListItem over to this res.render and we're 155 13:37.510 --> 13:42.940 going to call it exactly the same as what we have in our template page which is newListItem and we're 156 13:42.940 --> 13:49.630 going to pass in the value of this item that we've got over here. And inside our post request instead 157 13:49.630 --> 13:57.140 of trying to res.render, we're simply going to say res.redirect. And we're going to re 158 13:57.150 --> 13:59.980 direct to our home route. 159 14:00.010 --> 14:09.460 So what this does is when a post request is triggered on our home route, we'll save the value of new 160 14:09.460 --> 14:16.960 item in that text box to a variable called item and it will redirect to the home route which then 161 14:16.960 --> 14:21.960 gets us over here and triggers the app.get for our home route. 162 14:22.330 --> 14:29.890 And it will res.render the list template passing in both the kindOfDay as well as the newList 163 14:29.980 --> 14:30.940 Item. 164 14:30.940 --> 14:34.990 Now it's a little bit convoluted and it is quite roundabout. So you might have to play around with this 165 14:34.990 --> 14:37.570 code in order to fully understand what's going on. 166 14:37.660 --> 14:40.270 But we now have another problem. 167 14:40.270 --> 14:50.170 So if I-- so if I hit save and I refresh our page you can see that it says that item is not defined. 168 14:50.440 --> 14:54.240 And that's telling you that in your app.js on line 169 14:54.280 --> 14:57.420 26, item is not defined. 170 14:57.420 --> 15:07.300 So on this line at this point it can't access this variable called item because item was created inside 171 15:07.300 --> 15:08.330 the post route. 172 15:08.380 --> 15:14.290 In fact item only exists when we make a post request to our server. 173 15:14.290 --> 15:21.100 So once the users type something into that text box do we actually create this variable called item. 174 15:21.100 --> 15:27.340 If we try to pass it in here when it doesn't exist, that's why we get this particular error. And this 175 15:27.340 --> 15:34.360 problem is related to something that we call scope in programming. And in the next lesson we're going 176 15:34.360 --> 15:36.890 to be exploring scope in more detail. 177 15:37.030 --> 15:44.240 But let me show you how you can fix this. Instead of having our variable created over here 178 15:44.500 --> 15:48.540 we can create our variable at the top of our file. 179 15:48.610 --> 15:54.000 So let's create this item variable and let's set it to equal nothing. 180 15:54.070 --> 15:55.950 So a empty string. 181 15:56.080 --> 16:04.270 And when we do receive a post request then we reset the item variable to whatever it is that the user 182 16:04.270 --> 16:06.750 typed into the text box. 183 16:06.760 --> 16:12.070 So for some of you guys you might have spotted that if we write a code like this we'll have a bit of 184 16:12.070 --> 16:20.140 a problem because whenever we create a new post request then we replace the value of this item variable 185 16:20.320 --> 16:24.220 and this li becomes the latest item. 186 16:24.220 --> 16:25.750 So let me show you what I mean. 187 16:25.780 --> 16:31.060 So you can see the last item in our list is ;Eat more food.' If I add another one 188 16:31.090 --> 16:34.290 say Another and I hit add, 189 16:34.360 --> 16:43.150 then it replaces our last item instead of what we want which is to add another li below the previous 190 16:43.150 --> 16:43.860 one. 191 16:43.870 --> 16:52.210 So essentially our code at the moment only lets us store one piece of data under this variable called 192 16:52.330 --> 16:55.810 item and the old ones will get overwritten. 193 16:55.810 --> 17:00.360 So what we need is to store our items in a collection. 194 17:00.460 --> 17:03.540 So let's create an array. 195 17:03.940 --> 17:08.180 So instead of having our variable being item, let's call items. 196 17:08.690 --> 17:16.030 And this is now going to be a array and it's going to start out being empty but every single time we 197 17:16.030 --> 17:25.640 get a new post request and we create a new variable called item, then we can append that item to our 198 17:25.640 --> 17:27.440 array called items. 199 17:27.730 --> 17:36.640 So items.push and the object we want to push is the new item that we got from our post request. 200 17:37.270 --> 17:45.500 And when we pass it over to render our list view, then we're going to pass over our entire array. 201 17:45.680 --> 17:54.720 So now if we hit save and refresh, you can see that we have a new problem. Instead of creating new lis 202 17:54.850 --> 18:00.540 we're simply just rendering our array inside the single li. 203 18:00.810 --> 18:04.070 And that's because if we have a look inside our list. 204 18:04.090 --> 18:05.120 ejs, 205 18:05.380 --> 18:14.390 all it's doing is just planting whatever it is that we got sent over inside this list item element. 206 18:14.880 --> 18:21.510 And so if newListItem happens to be an array then all of that just gets put in here and rendered as 207 18:21.570 --> 18:25.300 a single list item which is not what we want. 208 18:25.320 --> 18:31.740 We want them to be all separate list items and we want to create new lis for every single new item 209 18:31.830 --> 18:33.460 we add to our list. 210 18:33.480 --> 18:41.250 So what we would need to happen is when we pass over an array or a collection like this, we want to loop 211 18:41.370 --> 18:47.630 through it and create a new li for each item inside the array. 212 18:47.730 --> 18:51.150 So essentially we would need to create a FOR loop. 213 18:51.180 --> 18:53.080 So here's a challenge. 214 18:53.190 --> 19:03.300 I want you to replace this line of code with a FOR loop using the EJS snippets that we learned 215 19:03.300 --> 19:09.690 about in the last lesson so that we can loop through all of the items in the array and we're going to 216 19:09.690 --> 19:15.470 create a single li that contains every single item inside this array. 217 19:15.720 --> 19:23.430 So by the end of it you should be able to add new lis every single time you type a new to do list 218 19:23.430 --> 19:29.070 item. 219 19:29.110 --> 19:30.520 All right so let's give this a go. 220 19:30.560 --> 19:36.920 Let's comment this line out and in it's place we're going to write a FOR loop. 221 19:36.950 --> 19:41.480 So if we're going to create a new traditional FOR loop then we're going to create a variable called 222 19:41.540 --> 19:45.170 i that's going to start off being equal to zero. 223 19:45.530 --> 19:53.790 And it's going to run while i is less than the newListItem array.length. 224 19:54.500 --> 19:59.220 And finally i is going to be incremented by 1 each time. 225 19:59.630 --> 20:04.640 And at this point it's probably a good idea to change the name of this to reflect the fact that it's 226 20:04.640 --> 20:05.660 now an array. 227 20:05.690 --> 20:08.160 It's not a single item anymore. 228 20:08.390 --> 20:13.540 So let's go ahead and change this to newListItems. 229 20:14.030 --> 20:17.940 And remember that means we have to change it here as well. 230 20:17.940 --> 20:25.980 And now we're going to create an li that is going to be newListItems at the index of i. 231 20:26.180 --> 20:29.990 So these lines of code loops through our array 232 20:30.260 --> 20:36.570 and for however many items there are in there, we're going to create a list item for each of them. 233 20:36.620 --> 20:43.970 So remember in order to run code inside our EJS file we of course have to add the snippets tag on 234 20:44.030 --> 20:46.000 each line where we have some code. 235 20:49.550 --> 20:56.230 And inside the li we're going to render the value of newListItems at index i. 236 20:56.240 --> 21:03.440 So we're going to use a slightly different tag which is the one that is a angled bracket, percentage 237 21:03.440 --> 21:10.480 sign, equals in order to get the value of a newListItem at index i. 238 21:10.670 --> 21:16.800 So let's delete our previous line of code and let's refresh our page. 239 21:16.820 --> 21:25.220 And now if I add a new item then you can see that for every single new item I have it will get added 240 21:25.220 --> 21:30.400 in to our ul and each item gets its own li. 241 21:30.410 --> 21:36.720 Now we can make our code even more succinct by simply deleting all of these lis. 242 21:38.270 --> 21:42.370 And instead we simply add it to our array. 243 21:42.530 --> 21:50.870 So our array starts off with three items, buy food, cook food and eat food, and all three items inside the 244 21:50.870 --> 21:54.890 items array will get loaded up into its own li 245 21:55.100 --> 22:05.830 as soon as we load up the page. And when we add new items then it will get added to the end of the list. 246 22:07.170 --> 22:16.050 So now our FOR loop takes care of rendering everything into a new li and it renders every single item 247 22:16.110 --> 22:19.220 that we add into our items array. 248 22:19.410 --> 22:27.930 So to summarize when we first load up our home page, we go through this route and we render our list 249 22:27.950 --> 22:35.630 .ejs passing in two variables: one called kindOfDay and another called newListItems. 250 22:35.910 --> 22:43.800 Now newListItems is set to equal the items array which starts off containing three strings, buy foo, 251 22:43.800 --> 22:44.350 cook food, 252 22:44.370 --> 22:45.190 eat food. 253 22:45.580 --> 22:52.130 And this gets passed into the list.ejs under this variable name newListItems. 254 22:52.170 --> 22:59.580 And over here we have a for loop that loops through the entire length of the newListItems array and 255 22:59.610 --> 23:04.480 it renders a new LI for each item inside the array. 256 23:04.770 --> 23:12.660 Now when a user adds a new item through the text input then that gets saved under the variable name 257 23:12.660 --> 23:21.850 newItem and we trigger a post request to the home route which will be caught by this block of code. 258 23:22.620 --> 23:27.230 And when we're inside this block of code we grab hold of the value of the newItem, 259 23:27.300 --> 23:30.400 so whatever it is that the user typed inside here, 260 23:31.020 --> 23:38.640 and then we save it to a variable called item and we add that item to our array called items. And then 261 23:38.700 --> 23:41.050 we redirect to the home route. 262 23:41.190 --> 23:43.520 So now we go back over here 263 23:43.770 --> 23:52.830 but the items array has now increased by a size of one and our new item get pushed onto the end of the 264 23:52.830 --> 23:53.570 array. 265 23:53.780 --> 24:03.030 And now we're able to go ahead and render list again and pass over the now updated array with all 266 24:03.030 --> 24:05.610 of our list items. 267 24:05.610 --> 24:12.210 So this is a really fundamental part of templating and that is passing data through from the server 268 24:12.270 --> 24:18.510 to our template and populating it with dynamic content. 269 24:18.510 --> 24:24.210 So if this is at all confusing I recommend trying it yourself. 270 24:24.270 --> 24:30.990 So trying to build the website as we have it right now by yourself without watching the videos. 271 24:31.110 --> 24:35.820 So it might take a couple of gos and you might have to come back to the videos to refresh yourself 272 24:36.120 --> 24:38.490 and remind yourself of how things are done 273 24:38.550 --> 24:44.220 but this requires a little bit of repetition on your part and playing around with the code passing in 274 24:44.220 --> 24:50.910 different things, looping through it, or using IF statements, using FOR statements on the EJS side 275 24:51.030 --> 24:54.280 and rendering it inside the template. 276 24:54.570 --> 25:01.080 But after you're done, in the next lesson we're going to talk about a concept in programming known as 277 25:01.170 --> 25:02.250 scope. 278 25:02.260 --> 25:05.370 So for all of that and more, I'll see you on the next lesson.