All language subtitles for 007 Revisiting Lodash and Deleting Items from Custom ToDo Lists_en

af Afrikaans
ak Akan
sq Albanian
am Amharic
ar Arabic
hy Armenian
az Azerbaijani
eu Basque
be Belarusian
bem Bemba
bn Bengali
bh Bihari
bs Bosnian
br Breton
bg Bulgarian
km Cambodian
ca Catalan
ceb Cebuano
chr Cherokee
ny Chichewa
zh-CN Chinese (Simplified)
zh-TW Chinese (Traditional)
co Corsican
hr Croatian
cs Czech
da Danish
nl Dutch
en English
eo Esperanto
et Estonian
ee Ewe
fo Faroese
tl Filipino
fi Finnish
fr French Download
fy Frisian
gaa Ga
gl Galician
ka Georgian
de German
el Greek
gn Guarani
gu Gujarati
ht Haitian Creole
ha Hausa
haw Hawaiian
iw Hebrew
hi Hindi
hmn Hmong
hu Hungarian
is Icelandic
ig Igbo
id Indonesian
ia Interlingua
ga Irish
it Italian
ja Japanese
jw Javanese
kn Kannada
kk Kazakh
rw Kinyarwanda
rn Kirundi
kg Kongo
ko Korean
kri Krio (Sierra Leone)
ku Kurdish
ckb Kurdish (Soranî)
ky Kyrgyz
lo Laothian
la Latin
lv Latvian
ln Lingala
lt Lithuanian
loz Lozi
lg Luganda
ach Luo
lb Luxembourgish
mk Macedonian
mg Malagasy
ms Malay
ml Malayalam
mt Maltese
mi Maori
mr Marathi
mfe Mauritian Creole
mo Moldavian
mn Mongolian
my Myanmar (Burmese)
sr-ME Montenegrin
ne Nepali
pcm Nigerian Pidgin
nso Northern Sotho
no Norwegian
nn Norwegian (Nynorsk)
oc Occitan
or Oriya
om Oromo
ps Pashto
fa Persian
pl Polish
pt-BR Portuguese (Brazil)
pt Portuguese (Portugal)
pa Punjabi
qu Quechua
ro Romanian
rm Romansh
nyn Runyakitara
ru Russian
sm Samoan
gd Scots Gaelic
sr Serbian
sh Serbo-Croatian
st Sesotho
tn Setswana
crs Seychellois Creole
sn Shona
sd Sindhi
si Sinhalese
sk Slovak
sl Slovenian
so Somali
es Spanish
es-419 Spanish (Latin American)
su Sundanese
sw Swahili
sv Swedish
tg Tajik
ta Tamil
tt Tatar
te Telugu
th Thai
ti Tigrinya
to Tonga
lua Tshiluba
tum Tumbuka
tr Turkish
tk Turkmen
tw Twi
ug Uighur
uk Ukrainian
ur Urdu
uz Uzbek
vi Vietnamese
cy Welsh
wo Wolof
xh Xhosa
yi Yiddish
yo Yoruba
zu Zulu
Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated: 1 00:00:00,480 --> 00:00:04,410 So now the functionality for our ToDo list 2 00:00:04,410 --> 00:00:07,500 version 2 is almost complete. 3 00:00:07,500 --> 00:00:13,770 We're able to access our default list on the home page and we can add new items here 4 00:00:14,070 --> 00:00:16,230 which gets added to our database. 5 00:00:16,230 --> 00:00:22,450 We can delete them from our database and we can also create custom lists 6 00:00:22,470 --> 00:00:24,620 for example one called shopping 7 00:00:25,050 --> 00:00:25,310 right? 8 00:00:25,310 --> 00:00:31,890 So we now have a new list with three default items and we can write something like "Buy milk" and it will get 9 00:00:31,950 --> 00:00:36,540 added to that particular list and all of this gets persisted. 10 00:00:36,540 --> 00:00:43,920 So whatever it is that we decide to save into the home list or into the worklist then they always stay 11 00:00:43,920 --> 00:00:47,840 where they're meant to be associated with that particular list. 12 00:00:48,330 --> 00:00:55,050 So the last thing that we need to do is we need to be able to delete these items in our custom lists 13 00:00:55,590 --> 00:01:04,950 because at the moment when I check this off then it somehow redirects me back to my home page instead 14 00:01:05,010 --> 00:01:09,910 of actually deleting the item that I wanted from that custom list. 15 00:01:09,930 --> 00:01:11,160 You can see it's still there right? 16 00:01:11,170 --> 00:01:14,440 So why is this? 17 00:01:14,710 --> 00:01:22,480 Well, if you take a look inside our list.ejs at the moment the way that we're implementing the delete 18 00:01:22,480 --> 00:01:30,850 functionality is through the use of this form. And this form makes a post request to the /delete 19 00:01:30,850 --> 00:01:40,750 route and it passes over the item id that the user wanted to delete and the form gets triggered when 20 00:01:40,780 --> 00:01:43,390 one of the checkboxes gets clicked. 21 00:01:43,390 --> 00:01:47,360 So here's a problem. In that route 22 00:01:47,360 --> 00:01:55,790 we only look for all of the items but we don't currently check which list the item is from in order 23 00:01:55,790 --> 00:01:59,130 to delete it from the correct list. 24 00:01:59,150 --> 00:02:05,840 So the first thing we need is that when we tap into this route we need two pieces of information: the 25 00:02:05,870 --> 00:02:13,880 ID of the checked item but we also need to know which list that item came from. In this form 26 00:02:13,880 --> 00:02:20,180 there isn't a submit button right? Where we can put in our list title and pass that over when the form 27 00:02:20,180 --> 00:02:21,650 gets submitted. 28 00:02:21,650 --> 00:02:27,770 There's no other input other than our checkbox which already has a value and we definitely need that 29 00:02:27,770 --> 00:02:30,300 value of the item ID. 30 00:02:30,710 --> 00:02:31,910 What can we do here? 31 00:02:32,830 --> 00:02:39,950 Rather handily in the list of inputs that we get from HTML, there's one which has a type of 32 00:02:40,000 --> 00:02:41,150 hidden. 33 00:02:41,260 --> 00:02:48,250 And this allows us to include data that can't be seen or modified by users when a form is submitted. 34 00:02:48,280 --> 00:02:57,240 For example the id of the content or in our case the list name. So inside here just before the form 35 00:02:57,270 --> 00:02:57,870 ends, 36 00:02:57,870 --> 00:03:08,710 I'm going to add a new input and this input is going to have a type of hidden. And it's also going to 37 00:03:08,710 --> 00:03:15,340 have a name so that I can refer to it when I look at my req.body and the name for this is going 38 00:03:15,340 --> 00:03:18,300 to be called just listName. 39 00:03:18,490 --> 00:03:20,720 And finally it's going to have a value 40 00:03:20,800 --> 00:03:23,500 and this is where the neat part comes in. 41 00:03:23,500 --> 00:03:26,750 We're going to use that EJS tag again 42 00:03:27,070 --> 00:03:34,860 and inside here we're going to insert that listTitle that we already have access to. 43 00:03:35,160 --> 00:03:42,930 And now we can close off our inputs and make sure that we add a closing input tag because it's not 44 00:03:42,960 --> 00:03:44,820 a self closing tag, 45 00:03:44,970 --> 00:03:47,840 these inputs. 46 00:03:47,860 --> 00:03:56,260 So now if we hit save and we head back to our app.js in our post to our delete route we can now 47 00:03:56,290 --> 00:04:04,030 check to see what is the value of that listName. So we can create a new constant and we can call it 48 00:04:04,030 --> 00:04:05,420 list name. 49 00:04:06,340 --> 00:04:15,460 And we're going to set it to equal req.body.listName. And just check to make sure that is 50 00:04:15,460 --> 00:04:18,070 the same as it got here. 51 00:04:18,399 --> 00:04:20,260 So yep! Looks good. 52 00:04:20,260 --> 00:04:27,010 So the next thing we need to do is we're going to again use an IF statement to check to see if we are 53 00:04:27,310 --> 00:04:35,710 making a post request to delete an item from the default list where the listName is today or if we're 54 00:04:35,710 --> 00:04:44,680 trying to delete an item from a custom list. We're saying if listName is equal to today then that means 55 00:04:44,770 --> 00:04:49,750 we're on the default list and we can do everything as we did previously. 56 00:04:49,750 --> 00:04:56,150 So we'll just cut and paste that into that if block, but what about the else block? 57 00:04:56,290 --> 00:05:00,120 Well this is the case where the list name is not today 58 00:05:00,460 --> 00:05:06,520 so that delete request is actually coming from a custom list. 59 00:05:06,560 --> 00:05:14,060 In this case we need to be able to find the list document that has the current listName and then we 60 00:05:14,060 --> 00:05:20,820 need to update that list to remove the checked item with that particular ID. 61 00:05:21,050 --> 00:05:28,700 Now because inside our list document there's an array of item documents 62 00:05:28,700 --> 00:05:36,290 then it's actually a little bit more complex because we basically have to find an item inside this array. 63 00:05:36,320 --> 00:05:42,860 We have to basically trawl through this array and find an item with a particular ID and then remove 64 00:05:42,890 --> 00:05:46,750 the entire item from the array. 65 00:05:46,760 --> 00:05:48,310 There's a few ways of doing this. 66 00:05:48,350 --> 00:05:53,500 You can of course use FOR loops and use the Javascript filter method, 67 00:05:53,660 --> 00:05:56,590 but let's see if there's actually a simpler way. 68 00:05:58,530 --> 00:06:08,430 If we head over to Google and we simply just search for "mongoose remove document from array". That seems 69 00:06:08,880 --> 00:06:11,680 pretty much like what we've been trying to do 70 00:06:11,700 --> 00:06:12,360 right? 71 00:06:12,690 --> 00:06:17,420 Let's see what the first non-ad Stack Overflow post says. 72 00:06:17,910 --> 00:06:24,750 So in this case they're saying you want to delete an array element in a document and then save. 73 00:06:24,750 --> 00:06:29,140 So that sounds kind of similar to what we wanted to do. 74 00:06:29,460 --> 00:06:37,670 If we look at the answer, the first answer says that you can do that directly in MongoDB. And you 75 00:06:37,670 --> 00:06:45,260 can use one of the pull or pullAll operators to remove an item from the array. 76 00:06:45,260 --> 00:06:47,950 Now we have a bit of a hint to go on. 77 00:06:47,990 --> 00:06:52,190 So we need to use this thing pull or pullAll. 78 00:06:52,360 --> 00:06:59,530 So let's search the MongoDB docs and we're going to look for this pull operator to find out a bit 79 00:06:59,530 --> 00:07:00,970 more information about it. 80 00:07:02,420 --> 00:07:11,210 So it tells you that the pull operator removes from an existing array all instances of a value or values 81 00:07:11,480 --> 00:07:18,480 that match a specified condition. And they've shown you an example of how you can use this. 82 00:07:18,620 --> 00:07:28,520 So we can use this along with the Mongoose method which is called findOneAndUpdate to combine these 83 00:07:28,520 --> 00:07:35,000 two together in order to achieve what it is that we need because with Mongoose alone or with Javascript 84 00:07:35,010 --> 00:07:38,870 alone we can actually get this really neat pull functionality. 85 00:07:38,960 --> 00:07:45,260 We have to use something that's fundamental to MongoDB. And all the operators that's preceded by a 86 00:07:45,260 --> 00:07:51,800 dollar sign comes from MongoDB. And you can see if you scroll down there's actually a whole bunch of 87 00:07:51,890 --> 00:07:57,860 other operators you can use as well but this one is far more efficient than if we tried to loop through 88 00:07:57,860 --> 00:08:03,440 all of the items in our array, reading each of them and then removing them through the filter method that 89 00:08:03,440 --> 00:08:04,830 Javascript gives us. 90 00:08:04,940 --> 00:08:10,460 This is just a slightly more efficient way of getting to the end result which we found through just 91 00:08:10,460 --> 00:08:13,120 doing a quick Google search. 92 00:08:13,170 --> 00:08:14,610 This is what the mongoose 93 00:08:14,610 --> 00:08:15,520 findOne 94 00:08:15,530 --> 00:08:23,100 AndUpdate syntax looks like. We first specify the model which corresponds to the collection that we want 95 00:08:23,100 --> 00:08:25,710 to find one and update from, 96 00:08:25,890 --> 00:08:27,960 and then we call findOneAndUpdate 97 00:08:28,230 --> 00:08:30,960 and finally we provide three things: 98 00:08:30,990 --> 00:08:33,720 one is the filter conditions, 99 00:08:33,720 --> 00:08:35,500 what do we want to find right? 100 00:08:35,520 --> 00:08:37,030 This is the query. 101 00:08:37,289 --> 00:08:40,659 And then the second one is well, what do you want to update? 102 00:08:40,770 --> 00:08:47,610 And the final thing is a callback where we get the results of what we found based on those conditions. 103 00:08:49,150 --> 00:08:54,340 So in our case the conditions we've already seen before and the callback we've really seen before. 104 00:08:54,460 --> 00:08:58,670 But in this part where we have to provide the updates, how do we actually do it? 105 00:08:58,810 --> 00:09:00,650 Well let's break it down a little bit more. 106 00:09:00,910 --> 00:09:02,950 We want to use the pull operator. 107 00:09:03,070 --> 00:09:11,470 So inside there, we have to specify the $pull operator as a key and then the value has to be the field 108 00:09:11,470 --> 00:09:13,020 that we want to pull from, 109 00:09:13,210 --> 00:09:15,810 so this has to be an array of something. 110 00:09:15,910 --> 00:09:23,050 In our case is an array of items. And then we have to provide a value for that field, which item in tha 111 00:09:23,110 --> 00:09:24,170 array of items. 112 00:09:24,250 --> 00:09:26,240 do we actually want to pull? 113 00:09:26,380 --> 00:09:30,050 So the final syntax looks something like this. 114 00:09:30,430 --> 00:09:33,670 And it's a little bit complex which is why I broke it down. 115 00:09:33,670 --> 00:09:37,980 But essentially we're saying we want to pull from a particular array 116 00:09:38,230 --> 00:09:45,970 and the way that we're going to find the item inside that array is through its ID or through its name 117 00:09:46,060 --> 00:09:48,170 or whatever it is you want to choose. 118 00:09:48,370 --> 00:09:50,160 And then we have to provide the value. 119 00:09:50,200 --> 00:09:53,790 So let's understand this a little bit better by seeing it in action. 120 00:09:55,330 --> 00:10:02,140 Inside our delete route and inside this ELSE block where we've checked that the list that the delete request 121 00:10:02,140 --> 00:10:04,530 came from is not our default list, 122 00:10:04,570 --> 00:10:13,090 we're going to tap into our list model and we're going to call findOneAndUpdate and just make sure 123 00:10:13,090 --> 00:10:14,590 you don't have any typos in there. 124 00:10:16,040 --> 00:10:18,890 And then we have to specify three things right? 125 00:10:18,890 --> 00:10:20,970 The first is the condition, 126 00:10:21,020 --> 00:10:24,140 so which list do you want to find? 127 00:10:24,470 --> 00:10:26,390 And we're only going to get one back, 128 00:10:26,390 --> 00:10:29,440 remember. This is how findOne works. 129 00:10:29,450 --> 00:10:32,750 The second thing is what updates do we want to make? 130 00:10:33,050 --> 00:10:36,200 And the last thing is simply just a callback. 131 00:10:36,200 --> 00:10:40,210 Now in the first part this is quite easy. 132 00:10:40,280 --> 00:10:48,200 The list that we want to find has to have a name that corresponds to this listName constant that we 133 00:10:48,200 --> 00:10:49,480 got from our list. 134 00:10:49,500 --> 00:10:51,830 ejs. Let's put that in there. 135 00:10:51,830 --> 00:10:58,220 This is going to be the name of our custom list. Now that we found that document that corresponds to 136 00:10:58,220 --> 00:10:59,540 the customer list, 137 00:10:59,570 --> 00:11:02,020 how are we going to update it? 138 00:11:02,540 --> 00:11:10,190 Well first we need to use the pull operator, and then we're going to specify something that we want to 139 00:11:10,190 --> 00:11:18,890 pull from and here we have to provide the name of the array inside this list that we found and that 140 00:11:18,890 --> 00:11:22,140 name is of course going to be items. 141 00:11:22,160 --> 00:11:27,410 This is the only thing that's an array inside our list document. 142 00:11:27,420 --> 00:11:31,970 So now we can say pull from the items array. 143 00:11:32,010 --> 00:11:36,950 Now how do we know which item out of all of the items we want to pull? 144 00:11:37,140 --> 00:11:44,540 Well here's another further set of curly braces where we provide the query for matching the item. 145 00:11:44,640 --> 00:11:51,600 The query we're going to make is we're going to pull the item which has an ID that corresponds to the 146 00:11:51,630 --> 00:11:53,830 checkedItemId. 147 00:11:54,300 --> 00:11:56,850 So we're going to put that in there. 148 00:11:57,390 --> 00:12:05,340 And now this three layered cake is finally complete and this is the entirety of our update statement 149 00:12:05,830 --> 00:12:13,540 where we pull from our items array an item that has an ID that corresponds to our checkedItemId. 150 00:12:13,590 --> 00:12:15,940 And finally we're ready to write our callback. 151 00:12:15,990 --> 00:12:23,550 So again it's going to be a callback that gives you an error and a found list because in this case when we're 152 00:12:23,550 --> 00:12:29,910 calling findOneAndUpdate the find one corresponds to finding a list. 153 00:12:29,910 --> 00:12:39,680 Now that we've found the list and we've updated it then if there are no errors we can simply res. 154 00:12:39,910 --> 00:12:48,130 redirect. And we're going to redirect again to that custom list path 155 00:12:48,150 --> 00:12:54,600 so it's going to be "/" + listName. 156 00:12:54,810 --> 00:12:59,090 We're finally ready to save and test our app. 157 00:12:59,220 --> 00:13:06,840 So if we're on the work route, let's just refresh that page, and I decided to delete this item. 158 00:13:06,840 --> 00:13:13,550 Hit this to delete an item, then I click on it it gets deleted I get redirected back to the same list. 159 00:13:13,710 --> 00:13:15,960 Let's delete another one just to be sure. 160 00:13:16,020 --> 00:13:18,150 Again I get redirected to the same list. 161 00:13:18,180 --> 00:13:24,320 So now we're able to create custom lists and we get to add items 162 00:13:26,900 --> 00:13:35,720 and we get to delete items from our custom list as well as adding items to our default list and deleting 163 00:13:35,720 --> 00:13:36,940 them there as well. 164 00:13:38,560 --> 00:13:46,120 Now there's just one last niggling thing which is when we create our route parameters as we saw previously 165 00:13:46,420 --> 00:13:52,120 it actually differentiates between a lower case work and a upper case work. 166 00:13:52,120 --> 00:13:59,170 So in this case I'm trying to access localhost:3000/home with a lowercase "h" and 167 00:13:59,200 --> 00:14:04,850 you can see here I get this list that has a title of lowercase home. 168 00:14:04,900 --> 00:14:11,530 So let's go ahead and add a new item, "Buy sofa" to our home list. 169 00:14:11,530 --> 00:14:18,990 Now if I switch over to /Home, then it's a completely different list right? 170 00:14:19,000 --> 00:14:23,620 And that's crazy because the user probably wanted the same list. 171 00:14:23,650 --> 00:14:33,470 How can we solve this? What if we always wanted the capitalized version of the list in our title? 172 00:14:33,530 --> 00:14:41,180 How can we change whatever inputs that the user makes into that custom listName and change that string 173 00:14:41,270 --> 00:14:42,880 into a title case? 174 00:14:43,040 --> 00:14:46,100 So always capitalize the first letter. 175 00:14:46,670 --> 00:14:49,150 There's again lots of ways of doing this 176 00:14:49,340 --> 00:14:53,290 but the easiest way is just to simply use trusty Lodash. 177 00:14:53,570 --> 00:15:00,500 So let's go ahead and exit out of our server and let's npm install Lodash. 178 00:15:00,530 --> 00:15:05,980 Now while that's doing its thing, let me just show you the documentation for Lodash. 179 00:15:06,110 --> 00:15:14,770 If you scroll all the way down to the strings section you can see that we tried out kebab case, lower 180 00:15:14,770 --> 00:15:16,840 case, lower case first, 181 00:15:17,140 --> 00:15:23,890 but there's also this one called capitalize. And if you read through the docs you'll see that this one 182 00:15:23,980 --> 00:15:30,240 converts the first character of a string to uppercase and the remaining to lowercase. 183 00:15:30,250 --> 00:15:37,420 So that means even if you write all caps FRED or all lowercase fred, whatever it may be, it'll always just 184 00:15:37,420 --> 00:15:44,770 capitalize that string and only change the first letter to uppercase and all the rest to lowercase. We 185 00:15:44,770 --> 00:15:52,330 can add Lodash into our app with the Lodash convention which is a underscore and we're going to let it 186 00:15:52,390 --> 00:15:57,170 equal require "lodash". 187 00:15:57,250 --> 00:16:04,940 So now whenever we need some functionality we can just tap into it using that underscore. And the place 188 00:16:04,940 --> 00:16:09,030 where we need it is inside this route. 189 00:16:09,050 --> 00:16:14,390 So instead of setting the customListName to just simply whatever it is that the user typed in here, 190 00:16:14,780 --> 00:16:22,340 we're going to modify it to make it capitalized. And we can call that method by simply saying _ 191 00:16:22,520 --> 00:16:29,800 .capitalize and then inside the parentheses we'll provide a string just as you can see in this example. 192 00:16:30,720 --> 00:16:37,520 Here we're going to say customListName is equal to _.capitalize 193 00:16:37,680 --> 00:16:44,820 and remember because we're working with stuff created by people in America we have to respect the spelling. 194 00:16:44,820 --> 00:16:49,570 So it's a capitalize with a "z" instead of a "s". 195 00:16:49,840 --> 00:16:58,010 So now if we hit save and we go back to our console and we restart our server with nodemon. 196 00:16:58,660 --> 00:17:05,290 Now before we test our app we first have to drop our current collection because if you check out db 197 00:17:05,290 --> 00:17:13,450 .lists.find you can see we currently have the uppercase home, the lowercase home and it's all 198 00:17:13,660 --> 00:17:14,220 a mess. 199 00:17:14,260 --> 00:17:18,650 And this is before we enabled that functionality using Lodash. 200 00:17:18,880 --> 00:17:25,460 So let's go ahead and do db.lists.drop and hit enter. 201 00:17:25,480 --> 00:17:26,920 Now that's been executed. 202 00:17:26,950 --> 00:17:31,050 So if we do db.list.find you can see it's completely empty. 203 00:17:31,050 --> 00:17:35,790 Now let's go ahead and try to navigate to localhost:3000 204 00:17:35,800 --> 00:17:39,830 /work with the lowercase "w". 205 00:17:40,120 --> 00:17:45,760 And remember that Chrome loves to auto suggest. So sometimes you might think you're going to the capital 206 00:17:45,760 --> 00:17:50,140 one but it actually automatically redirected you to the lowercase one. 207 00:17:50,140 --> 00:17:53,780 So just to be sure just click on the one that you see in here. 208 00:17:53,890 --> 00:18:04,000 So here I'm going to /work and now I'm going to add a new item "Write emails" and 209 00:18:04,030 --> 00:18:10,790 hit add. And then I'm going to change this to the capital version of work, 210 00:18:10,840 --> 00:18:11,670 hit enter. 211 00:18:11,770 --> 00:18:18,180 You can see I'm still on the same list. And it's the same thing if we change that to lowercase 212 00:18:18,220 --> 00:18:24,850 home, it'll always redirect me to the list with a capitalized name. 213 00:18:25,030 --> 00:18:30,780 Even if I decide to do something really crazy like "HOMe". 214 00:18:30,900 --> 00:18:38,920 So something that just completely messes up the casing then I still get taken to the right page. 215 00:18:38,930 --> 00:18:45,650 I hope you enjoyed building this along with me and learning how to add a database to our Node.js apps 216 00:18:45,920 --> 00:18:54,650 that will make your apps infinitely more powerful and be able to permanently store your user data. In 217 00:18:54,650 --> 00:18:55,750 the next lesson 218 00:18:55,760 --> 00:19:03,200 it's your turn to add a database to the blog website that you created earlier on and it's finally time 219 00:19:03,230 --> 00:19:06,200 to actually turn it into a real product. 220 00:19:06,200 --> 00:19:09,080 So for all of that and more, I'll see you on the next lesson. 22938

Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.