WEBVTT 0 00:01.080 --> 00:06.570 Now the next question is how can we do that same thing that we did in our command line when we said 1 00:06.630 --> 00:12.780 find and we managed to grab hold of all of our documents inside our items collection? 2 00:12.840 --> 00:15.610 How can we do that inside our app.js 3 00:15.870 --> 00:22.350 so that we can actually send it over to our list.ejs to render in our ToDo list? 4 00:22.400 --> 00:25.440 This is what the Mongoose find method looks like. 5 00:25.460 --> 00:29.420 We specify the model name and then we specify some conditions 6 00:29.630 --> 00:34.720 and then we get a callback which includes an error and the results from the find 7 00:34.820 --> 00:35.930 if there were any. 8 00:36.110 --> 00:40.440 And then we can use the results documents inside that callback. 9 00:40.460 --> 00:48.950 So as a challenge I want to be able to log all of the items inside our items collection but do that 10 00:48.950 --> 00:50.210 from our app. 11 00:50.280 --> 00:56.510 js. Pause the video and try to complete the challenge. 12 00:56.530 --> 00:56.980 All right. 13 00:56.980 --> 01:02.000 So we're going to try and find them and then we're going to send them over to our list.ejs. 14 01:02.200 --> 01:07.300 So I'm going to call that Mongoose method right here inside my root route. 15 01:07.310 --> 01:13.420 I'm going to tap into the model which represents our collection of items and then I'm going to use that 16 01:13.420 --> 01:14.510 find method 17 01:14.560 --> 01:16.240 I spoke about earlier on. 18 01:16.450 --> 01:22.000 Now in this case the conditions for our find is actually pretty much just find all. 19 01:22.000 --> 01:26.970 So it's just going to be an empty set of curly braces. 20 01:27.010 --> 01:31.410 This will find us everything that's inside our items collection. 21 01:31.660 --> 01:39.550 And then once we found those items then we can trigger the callback which has an error and foundItems 22 01:40.030 --> 01:42.220 or anything you wish to call it really. 23 01:42.430 --> 01:47.220 But this is going to contain the things that we found inside the items collection. 24 01:47.560 --> 01:53.140 Now that we've got that we can log our found items 25 01:53.280 --> 02:01.130 and now I can get this method to trigger if I just go and access my home page or my root route. 26 02:01.130 --> 02:02.410 Let's save our app.js, 27 02:02.420 --> 02:11.180 let's go back into our terminal and I'm going to hit CONTROL + C to end my process and now I'm going 28 02:11.180 --> 02:13.420 to start it off with nodemon. 29 02:13.460 --> 02:19.170 This way it will run our app every single time I make some changes in our app.js. 30 02:19.760 --> 02:28.210 Now on Node server is up and running and if we go over to our localhost:3000 and hit refresh. 31 02:28.360 --> 02:36.910 So while we're able to log all of our items by using that find function that Mongoose gave us over here, 32 02:37.410 --> 02:43.870 our website is kind of broken because it doesn't know what this thing items is that we're trying to 33 02:43.870 --> 02:45.960 pass over to our list 34 02:45.980 --> 02:46.990 .ejs. 35 02:47.260 --> 02:49.480 And that's because items no longer exist 36 02:49.490 --> 02:57.910 right? Items referred to our items array which were deleted and instead we want to pass over the found 37 02:57.910 --> 02:59.450 Items instead. 38 02:59.740 --> 03:06.790 So let's go ahead and move our res.render into this callback here and instead of logging the found 39 03:06.790 --> 03:11.210 Items I'm going to pass over the foundItems to our list. 40 03:11.230 --> 03:13.120 ejs instead. 41 03:13.120 --> 03:16.690 So now if we hit save, nodemon should update our server 42 03:16.840 --> 03:23.110 and if we go ahead and refresh our website then you can see we no longer have any bugs but we still 43 03:23.110 --> 03:24.820 have some problems tho. 44 03:25.330 --> 03:33.130 And the first problem is that our items are being rendered in their entirety, like the entire document 45 03:33.220 --> 03:37.890 is being put into each one of our list items here. 46 03:38.910 --> 03:43.440 What we want is just the part that comes in the name field right? 47 03:43.440 --> 03:47.360 Not the whole ID and version and all of the rest of it. 48 03:47.370 --> 03:49.010 So that's problem number 1. 49 03:49.020 --> 03:57.540 Now problem number 2 is that every single time that we rerun our app.js with nodemon we insert more 50 03:57.540 --> 04:02.330 items into our database because it's rerunning this item. 51 04:02.460 --> 04:06.010 insertMany line of code. 52 04:06.250 --> 04:11.360 That means if I go over here and I just hit "rs" to restart my server 53 04:11.500 --> 04:19.270 now if I refresh my localhost:3000 I have even more items which is not what we want at all. 54 04:19.270 --> 04:21.650 We only want it to have three. 55 04:21.700 --> 04:25.400 So let's see how we can address these two problems. 56 04:25.420 --> 04:32.440 Now the first one is slightly easier to address. If we head over to our views and go over to our list 57 04:32.440 --> 04:40.600 .ejs then you can see that here we're rendering each of the list items just by carrying out a simple 58 04:40.630 --> 04:41.220 FOR loop. 59 04:41.230 --> 04:43.240 This is the traditional FOR loop 60 04:43.270 --> 04:44.520 right? 61 04:44.680 --> 04:50.290 And we're tapping into this thing called newListItems at the index i. 62 04:50.680 --> 04:59.510 And each of these items happens to be a document inside our items collection. Instead of adding the entirety 63 04:59.630 --> 05:04.640 of the documents collection we can simply tap into its name field. 64 05:05.030 --> 05:09.560 So now when I head back to my todo list and I refresh 65 05:09.560 --> 05:19.360 we're only putting in the name field of each of the items instead. Now the next thing I want to do is 66 05:19.450 --> 05:25.840 I want to give you a challenge. Because currently we're using these traditional FOR loop and it's making 67 05:25.840 --> 05:31.810 it a little bit cluttered and it's a little bit hard to see what's actually going on. As a challenge 68 05:31.810 --> 05:37.640 I want you to implement the for each method that we get access to in Javascript 69 05:37.680 --> 05:45.620 ES6 or new versions. Just as a reminder forEach syntax looks something like this. 70 05:45.850 --> 05:53.860 We tap into a method on an array. Every array in the newer versions of Javascript has access to this 71 05:53.860 --> 05:55.380 thing called forEach. 72 05:56.380 --> 06:03.820 And inside the forEach method we get to have a callback function and we get to tap into every single 73 06:03.820 --> 06:10.800 one of the items inside the array and then we get to use it inside the callback. 74 06:10.810 --> 06:19.930 Now as a challenge I want you to pause the video and rewrite our simple FOR loop into a forEach loop and 75 06:19.930 --> 06:21.490 still make it work 76 06:21.550 --> 06:27.540 when we reload our ToDo list website. 77 06:27.950 --> 06:29.610 All right so first things first. 78 06:29.660 --> 06:35.120 I'm going to leave our FOR loop aside and I'm going to rewrite it from scratch. 79 06:35.420 --> 06:41.960 The thing that we have access to over here is something called newListItems and that corresponds to 80 06:42.080 --> 06:47.700 all of the found items that we passed over inside our root route. 81 06:47.750 --> 06:55.370 That means we can tap into this thing called newListItems and we know it's an array of item documents. 82 06:55.370 --> 07:04.100 So therefore we can call the forEach loop on it. And inside the parentheses we pass in a callback function 83 07:04.430 --> 07:12.200 which allows us to tap into each item inside that array. And now we open up our callback 84 07:12.200 --> 07:19.150 and inside these curly braces we can use each of those to item documents. Inside here 85 07:19.170 --> 07:28.230 I'm going to copy and paste my div and instead of using the new list items at index i .name inside 86 07:28.320 --> 07:29.420 my paragraph, 87 07:29.490 --> 07:35.990 I'm just going to tap into that item object that I get access to now and type .name 88 07:36.000 --> 07:38.840 to access the name property. 89 07:39.240 --> 07:46.020 And now all I have to do because this is EJS, I'm going to include those little angle brackets and percentage 90 07:46.020 --> 07:49.950 signs around every single line where I have some code. 91 07:50.010 --> 07:54.060 So it's the first and the last line basically. 92 07:54.060 --> 08:02.940 So now I can go ahead and delete what remains of my traditional FOR loop and if I hit save and refresh 93 08:03.300 --> 08:09.840 we still get exactly the same appearances of our todo list and nothing has broken even though we've 94 08:09.840 --> 08:14.170 refactored our FOR loop to turn it into a forEach loop. 95 08:15.660 --> 08:20.940 Now the next problem we're going to tackle is all of these repeated inserts. 96 08:20.970 --> 08:28.170 The simplest solution which we did previously is we simply commented out this insertMany method after 97 08:28.170 --> 08:29.970 the first time it's run. 98 08:29.970 --> 08:36.090 But if you imagine that if our servers hosted somewhere like Heroku or somewhere else, we can't actually 99 08:36.090 --> 08:40.530 go in there after the first time it's run and then sort of comment out a function right? 100 08:40.530 --> 08:42.470 It doesn't really work. 101 08:42.480 --> 08:45.620 So how can we do this in a little bit of a better way? 102 08:47.230 --> 08:55.600 Well we kind of only want our default items to be inserted if our items collection is actually empty 103 08:55.600 --> 08:56.060 right? 104 08:56.200 --> 09:03.670 So we have to somehow check when a user accesses the root route whether if the items collection is empty 105 09:04.180 --> 09:10.300 in which case we're going to add all of our default items, but otherwise we're not going to add another 106 09:10.300 --> 09:16.850 set of default items in there. So the first thing we're going to do is we're going to clear out our database 107 09:17.420 --> 09:18.650 and we can do that 108 09:18.650 --> 09:21.410 the easiest inside our Mongo shell. 109 09:21.530 --> 09:27.300 So if we go ahead and see which DB, we're using. We're currently using the todolistDB. 110 09:27.470 --> 09:36.350 If I write "db.dropDatabase()" then I will execute the command to basically delete my 111 09:36.350 --> 09:37.220 database. 112 09:37.220 --> 09:42.980 So now if I write "show dbs" you can see the todolistDB no longer exists. 113 09:43.220 --> 09:48.650 So we have a blank slate and we're going to recreate it using our app.js. 114 09:48.690 --> 09:58.010 Now if I comment out this part where we're actually inserting our items into our items collection and I hit save, 115 09:58.380 --> 10:09.260 then when my app runs you can see I have no items at all. And if I tried to log my found items here then 116 10:09.290 --> 10:16.770 if I refreshed my homepage to tap into the root route and have a look in my console, then what I get is 117 10:16.790 --> 10:18.770 just an empty array. 118 10:18.830 --> 10:22.330 So an array with no items 119 10:22.370 --> 10:22.850 right? 120 10:23.940 --> 10:25.820 How can we check for this? 121 10:25.860 --> 10:33.460 How can we check to see if our collection of items is empty or if the array has no items? 122 10:33.840 --> 10:42.420 Well, we can simply use an IF statement and check what is the length of this array called foundItems 123 10:42.570 --> 10:48.540 because if it's equal to zero then that means we have the same condition as we have right now 124 10:48.540 --> 10:48.810 right? 125 10:48.810 --> 10:50.420 Just an empty array. 126 10:50.460 --> 10:53.740 We didn't find any items inside that collection. 127 10:54.150 --> 11:02.350 Well in that case and only in that case do we actually want to save our default data. 128 11:02.520 --> 11:13.550 So now I'm going to move this insertMany into here and I'm going to uncomment it to insert our default 129 11:13.610 --> 11:16.020 items into our database 130 11:16.010 --> 11:24.230 if there are currently no items in the collection. Else however I'm not going to add anything and I'm 131 11:24.230 --> 11:27.760 just going to render my list. 132 11:27.830 --> 11:31.260 ejs. Currently 133 11:31.460 --> 11:34.670 I have no items inside my items collection. 134 11:34.790 --> 11:43.850 If I hit save and I go into my browser and I hit refresh, you can see that inside my console it tells 135 11:43.850 --> 11:47.580 me that I've successfully saved my items to the database. 136 11:48.260 --> 11:52.510 But on the browser I'm not getting those items show up right? 137 11:52.520 --> 11:55.030 So how can I get it to do that? 138 11:55.040 --> 12:04.460 Well, if we take a look at the code when all items collection has no items then we simply just insert 139 12:04.460 --> 12:06.240 three new items in there. 140 12:06.530 --> 12:08.090 But then that's kind of the end 141 12:08.090 --> 12:09.840 right? We don't render anything. 142 12:09.860 --> 12:14.800 We don't try and render those items that we just added. As a shortcut 143 12:14.960 --> 12:23.220 what we can do is we can simply call res.redirect and we redirect back onto the root route. 144 12:23.480 --> 12:30.680 So what this will do is it'll check firstly to see if there are any items in our items collection and 145 12:30.770 --> 12:37.310 if there are none then it's going to create three items and add it into items collection. 146 12:37.310 --> 12:41.960 And then finally it's going to redirect back into this root route 147 12:42.050 --> 12:46.970 but now this time it's not going to fall into the IF block. 148 12:47.150 --> 12:55.160 Instead it's going to go into the ELSE block because now we actually do have items in our items collection 149 12:55.580 --> 13:01.490 and were able to res.render those new items over to our list. 150 13:01.530 --> 13:02.510 ejs. 151 13:02.540 --> 13:04.830 So let's run that again. 152 13:05.390 --> 13:12.770 And now you can see if we refresh our website we have all of our default items showing up but no matter 153 13:12.800 --> 13:20.720 how many times I restart my server I've still only got three items and it doesn't stop building up.