Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated:
1
00:00:00,970 --> 00:00:08,890
Currently as it is our list works in terms of all of the basic functionality. We're able to add new items,
2
00:00:08,950 --> 00:00:15,440
we're able to delete items and we're able to look at all of the items in our list.
3
00:00:15,760 --> 00:00:22,180
But there's one feature or one functionality that I would love to have for this app that we haven't
4
00:00:22,180 --> 00:00:26,630
currently implemented and it's the ability to have multiple lists
5
00:00:26,680 --> 00:00:27,240
right?
6
00:00:27,260 --> 00:00:30,150
There is no fun just having a single is to work off.
7
00:00:30,220 --> 00:00:36,280
So what if we were able to instead of going to the home page which is our default list what if we were
8
00:00:36,280 --> 00:00:43,480
able to just write /work and head over to the worklist and be able to see the items there.
9
00:00:43,480 --> 00:00:48,100
And what if we could create new lists on the fly like I wanted to create a home list,
10
00:00:48,220 --> 00:00:55,600
so if I type in the web address /home then I wanted to create a brand new page without me having
11
00:00:55,600 --> 00:01:02,890
to define all of the get and the post routes. We can use what we learn about express route parameters
12
00:01:03,010 --> 00:01:04,410
to do this.
13
00:01:04,420 --> 00:01:13,720
Express allows us to use route parameters to create dynamic routes. And so as a challenge I want you
14
00:01:13,720 --> 00:01:23,290
to delete this get route and instead create a dynamic route based on the route parameters so that if
15
00:01:23,290 --> 00:01:33,580
I go to localhost:3000/Home or /Work I should be up to print
16
00:01:33,910 --> 00:01:43,510
this last part of the URL inside the app.get. Again as a reminder this is what Express route parameters
17
00:01:43,510 --> 00:01:44,560
look like.
18
00:01:44,560 --> 00:01:45,960
We have a colon
19
00:01:46,240 --> 00:01:53,500
and then we have a parameter name and then inside the callback we get Access req.params. that
20
00:01:53,500 --> 00:01:54,470
parameter name.
21
00:01:54,520 --> 00:01:59,240
And this will equal the value that the user has typed in here.
22
00:01:59,440 --> 00:02:05,310
Pause the video and try to complete this challenge.
23
00:02:05,400 --> 00:02:08,650
So let's begin by creating our route.
24
00:02:08,729 --> 00:02:12,440
Maybe we'll create it just after the app.get up here.
25
00:02:12,810 --> 00:02:20,730
So I'm going to write app.get and instead providing a hardcoded route like /Work or
26
00:02:20,730 --> 00:02:21,960
/Home,
27
00:02:22,020 --> 00:02:29,700
I'm just going to write /: and then I'm going to call it customListName.
28
00:02:30,240 --> 00:02:35,800
And this is going to again accept a callback request and response.
29
00:02:36,090 --> 00:02:46,770
And then inside my callback I'm going to log req.params.customListName.
30
00:02:46,880 --> 00:02:53,920
So now let's hit save and go into our browser and I'm going to try and run this again.
31
00:02:53,970 --> 00:02:55,550
Localhos:3000
32
00:02:55,550 --> 00:02:57,310
/Home
33
00:02:57,460 --> 00:03:06,820
and now if I go into my console you can see I now have that part at the end here logged in my console.
34
00:03:06,960 --> 00:03:15,510
So I could change that to say work and if I go ahead and hit enter, then you can see I now get work logged
35
00:03:15,510 --> 00:03:16,300
in here.
36
00:03:16,350 --> 00:03:17,770
So far so good.
37
00:03:19,440 --> 00:03:25,760
Now instead of logging that param let's go ahead and save it into a constant and let's call that custom
38
00:03:25,770 --> 00:03:34,770
ListName. So customListName equals req.params.customListName and that comes from whatever
39
00:03:34,770 --> 00:03:42,610
it is that the user enters after the forward slash.Now that we have access to the name of the new list
40
00:03:42,730 --> 00:03:50,140
well we get to use it to create a new document and that document is going to have a slightly different
41
00:03:50,140 --> 00:03:52,870
schema than what items had.
42
00:03:52,950 --> 00:03:59,500
So right below where we have our default items I'm going to create a new schema and this one is going
43
00:03:59,500 --> 00:04:06,350
to be called listSchema. And this is going to take two fields:
44
00:04:06,350 --> 00:04:09,810
one is the name of the list which will be a string
45
00:04:09,950 --> 00:04:13,950
and the second is going to be an array of items.
46
00:04:14,120 --> 00:04:21,800
So the name of the field is going to be items and the value of the field is going to be an array of
47
00:04:21,980 --> 00:04:25,540
itemSchema based items.
48
00:04:25,550 --> 00:04:32,440
So now what we're saying is for every new list that we create the list is going to have a name and it's
49
00:04:32,450 --> 00:04:37,840
going to have an array of item documents associated with it as well.
50
00:04:39,360 --> 00:04:43,110
The next thing to do as always is to create our Mongoose model.
51
00:04:43,140 --> 00:04:51,330
This is going to be a constant called list and it's going to be equal to mongoose.model and then
52
00:04:51,330 --> 00:04:57,990
we're going to specify the singular version of our collection which is going to be called a list.
53
00:04:58,080 --> 00:05:02,060
And we're going to specify the schema which is listSchema.
54
00:05:02,830 --> 00:05:06,320
And make sure that you haven't got any typos like I have here
55
00:05:06,390 --> 00:05:10,410
"mongoose.mode" which should be "mongoose.model".
56
00:05:10,560 --> 00:05:17,880
So now that we've created our list model from our listSchema, then we're ready to create new list documents
57
00:05:17,970 --> 00:05:26,310
based off this model. And we're going to do that when a user tries to access a customListName. Inside
58
00:05:26,310 --> 00:05:26,850
this route
59
00:05:26,850 --> 00:05:33,330
I'm going to create a new list and this is going to be created based off our list model.
60
00:05:34,020 --> 00:05:36,240
And I have to fill in the two fields:
61
00:05:36,330 --> 00:05:42,440
one is the name of the list which is simply going to be whatever the user typed into the route.
62
00:05:42,510 --> 00:05:48,420
So if they said /Work or /Home then that's going to be the list name,
63
00:05:48,480 --> 00:05:50,630
so I'm going to put a customListName here.
64
00:05:51,030 --> 00:05:55,560
And then the second field is going to be the items.
65
00:05:56,160 --> 00:06:00,590
And this should accept an array of list items.
66
00:06:00,690 --> 00:06:07,230
And so when we create a new list that is a custom list we're going to give it the name based off the
67
00:06:07,230 --> 00:06:09,450
path that the user tried to access
68
00:06:09,450 --> 00:06:16,640
and then for the items we're simply going to start off with the same default items as we created previously.
69
00:06:16,920 --> 00:06:24,510
So previously when we made our default list we created 3 item documents and we packaged them all into
70
00:06:24,630 --> 00:06:25,570
an array.
71
00:06:25,740 --> 00:06:32,110
So we can now reuse this array to populate our custom lists.
72
00:06:32,130 --> 00:06:39,310
So inside here the items for my new list are simply going to be the default items.
73
00:06:39,510 --> 00:06:47,700
Now that we've created our new list document then all we have to do is call list.save to save that into
74
00:06:47,760 --> 00:06:50,580
the lists collection.
75
00:06:50,590 --> 00:06:58,300
Now if we save our app.js and we head over to our browser and we try to access for example
76
00:06:58,300 --> 00:07:06,700
localhost:3000/Home and we hit enter, then if we go into our Mongo shell and we
77
00:07:06,700 --> 00:07:14,260
just say "show collections" then you can see we now have a new collection and that collection is a collection
78
00:07:14,260 --> 00:07:15,350
of lists.
79
00:07:15,400 --> 00:07:24,220
So let's say "db.lists.find" and you can see that we have a single document inside our lists collection
80
00:07:24,580 --> 00:07:31,420
which has the name of home which corresponds to this part that we entered using the route parameters
81
00:07:31,930 --> 00:07:37,050
and then it has an array of items which correspond to our default items.
82
00:07:37,090 --> 00:07:38,430
"Welcome to your todolist!
83
00:07:38,440 --> 00:07:42,650
Hit the + button and then hit this to delete the item".
84
00:07:42,650 --> 00:07:44,460
So so far so good.
85
00:07:44,470 --> 00:07:46,760
That was pretty successful.
86
00:07:46,760 --> 00:07:48,400
Now here's the problem.
87
00:07:48,620 --> 00:07:55,420
When a user accesses local host or whatever the website domain will be /Home
88
00:07:55,610 --> 00:07:59,690
then we'll create a new list with that name home
89
00:07:59,700 --> 00:08:00,210
right?
90
00:08:00,530 --> 00:08:03,390
But we don't really want a whole bunch of them.
91
00:08:03,530 --> 00:08:08,140
What if it users already created the list and they simply want to access it?
92
00:08:08,150 --> 00:08:16,480
So for example if I head back over here and we stop this and try to head over to Home again then if
93
00:08:16,490 --> 00:08:23,180
we check our Mongo shell and we try to run "db.list.find" then you can see we now actually
94
00:08:23,180 --> 00:08:26,630
have two lists both called home
95
00:08:26,630 --> 00:08:27,380
right?
96
00:08:27,410 --> 00:08:29,020
So this is not what we want.
97
00:08:29,030 --> 00:08:35,980
We don't want to create a new list with the same name every time the user tries to access it. How can
98
00:08:35,980 --> 00:08:37,860
we solve this with code?
99
00:08:38,020 --> 00:08:46,270
Well, we have to check to see if a list with that name already exists in our collection of lists. And
100
00:08:46,270 --> 00:08:49,020
if it does then we're just going to display it
101
00:08:49,150 --> 00:08:53,710
but if it doesn't then we'll create a new one using the default items.
102
00:08:55,420 --> 00:09:04,060
So as a challenge, I want you to use the Mongoose method called findOne to find within our lists collection
103
00:09:04,390 --> 00:09:10,240
whether if there's a list that has the same name as the one that the user is currently trying to access.
104
00:09:10,900 --> 00:09:17,900
And if there is, then we're just going to log "exists" and if it doesn't exist then we'll log "doesn't exist".
105
00:09:17,920 --> 00:09:21,190
So pause the video and try to complete that challenge.
106
00:09:24,420 --> 00:09:24,690
All right.
107
00:09:24,690 --> 00:09:34,480
So just above where we create our list we're going to call findOne on our list model. And the condition
108
00:09:34,480 --> 00:09:36,160
we're going to give it is
109
00:09:36,160 --> 00:09:40,910
find me a list inside the collection of lists that has the name
110
00:09:40,960 --> 00:09:45,080
that's the same as the one that the user is currently trying to access,
111
00:09:45,280 --> 00:09:54,530
so custom list name. And once you've completed that then we'll have the callback function with error
112
00:09:54,680 --> 00:09:57,060
and foundList.
113
00:09:57,110 --> 00:10:00,410
So that means if there was an error then it'll print it,
114
00:10:00,430 --> 00:10:04,790
but if there wasn't then we should be have to tap into what was found.
115
00:10:04,790 --> 00:10:14,910
So we can say if there were no errors, then in that case we're going to check to see if there is or there
116
00:10:14,940 --> 00:10:17,510
isn't a foundList.
117
00:10:17,520 --> 00:10:24,180
Now it's important to differentiate between findOne and the one that we used previously which is find
118
00:10:24,240 --> 00:10:31,050
all essentially because this method is going to give us an array back as the result.
119
00:10:31,200 --> 00:10:35,330
And that's why we have to check to see if the array had a length of 0
120
00:10:35,370 --> 00:10:37,840
namely it had no items in it.
121
00:10:37,860 --> 00:10:39,300
It was an empty array.
122
00:10:39,630 --> 00:10:44,580
But in this case what we get is an object back because we're saying findOne
123
00:10:44,580 --> 00:10:49,010
so you'd only return one document if it is found.
124
00:10:49,110 --> 00:10:51,290
So we can't check it's length.
125
00:10:51,450 --> 00:10:54,840
But instead we can simply check to see if it exists or not
126
00:10:54,840 --> 00:10:55,550
right?
127
00:10:55,620 --> 00:10:57,510
If foundList doesn't exist
128
00:10:57,510 --> 00:11:02,580
well then in that case we'll log "Doesn't exist".
129
00:11:03,150 --> 00:11:11,760
But otherwise then it will log "Exists." Now let's give that a go
130
00:11:11,950 --> 00:11:13,810
and let's go into
131
00:11:16,520 --> 00:11:21,300
our website and we try to access localhost:3000/Home
132
00:11:21,560 --> 00:11:24,750
Let's hit enter and see what we get in our console.
133
00:11:24,770 --> 00:11:27,950
So let's switch back to this tab and it says "Exists".
134
00:11:28,280 --> 00:11:33,260
But what if we tried some sort of new one that we've obviously not made yet and
135
00:11:33,260 --> 00:11:36,420
hit enter and "Doesn't exist".
136
00:11:36,440 --> 00:11:36,830
Great!
137
00:11:36,860 --> 00:11:39,350
So our code seems to be working.
138
00:11:39,350 --> 00:11:46,120
So now instead of console logging we're going to go ahead and implement the code that we need. Here
139
00:11:46,130 --> 00:11:50,710
I'm going to write a comment saying this should be the path where we create a new list.
140
00:11:51,140 --> 00:11:57,380
And down here instead of this console log I'm going to have a comment that says this is a path where we should
141
00:11:57,470 --> 00:12:01,820
show an existing list.
142
00:12:01,820 --> 00:12:08,870
So if there were no list that were found that have the same name then we're going to create a new list.
143
00:12:08,990 --> 00:12:12,870
And the part of our code which does that is of course this section.
144
00:12:12,890 --> 00:12:19,860
So we'll just cut that and paste it into the IF and then we have the ELSE statement.
145
00:12:20,040 --> 00:12:24,020
So show an existing list if it already exists here.
146
00:12:24,180 --> 00:12:27,640
We're going to use that found list that we tapped into
147
00:12:27,930 --> 00:12:30,480
and we've really checked that it's definitely not nil,
148
00:12:30,480 --> 00:12:31,920
it definitely exists.
149
00:12:31,920 --> 00:12:39,130
So what we can do is we can call res.render and we're going to render our list.ejs
150
00:12:39,480 --> 00:12:46,080
and then the second parameter we're going to pass in is going to be the list title and also the items,
151
00:12:46,330 --> 00:12:48,610
so let's just copy that in here.
152
00:12:48,810 --> 00:12:53,770
Now the list title is no longer going to be a static word like today.
153
00:12:54,030 --> 00:12:57,250
Instead it's going to be the customListName right?
154
00:12:57,330 --> 00:13:05,590
So we could tap into this found list and we can say .name to tap into its name field.
155
00:13:05,910 --> 00:13:13,260
And for the items we do something quite similar. We say foundList.items
156
00:13:13,260 --> 00:13:20,230
and so now we'll tap into the name property and the items property and we'll send that over to list
157
00:13:20,250 --> 00:13:23,550
.ejs to populate that page.
158
00:13:23,550 --> 00:13:31,800
So now let's hit save and let's head back into our localhost:3000 which still works as it should.
159
00:13:31,800 --> 00:13:36,420
And this one of course has the default list with the static name of today.
160
00:13:36,600 --> 00:13:40,200
But let's go ahead and access our home list.
161
00:13:40,650 --> 00:13:46,830
So we've now got a home list and what if we try to create a new one, say a worklist.
162
00:13:51,760 --> 00:13:58,330
Well it seems like the list got created because if we check in our Mongo shell then you can see there's
163
00:13:58,330 --> 00:14:04,210
a whole bunch of stuff that got created but the last document that we added was this one with a name
164
00:14:04,300 --> 00:14:05,570
of work.
165
00:14:05,800 --> 00:14:10,780
If you wanted to clear out a particular collection because it's kind of gathering dust and it's got
166
00:14:10,780 --> 00:14:16,810
data from previous testing, then all you have to do is to make sure that you're inside the correct database,
167
00:14:16,810 --> 00:14:20,340
so I am, I'm using todolistDB.
168
00:14:20,890 --> 00:14:24,660
And then here we can show collections.
169
00:14:24,680 --> 00:14:35,810
So we've got items and lists and I can say "db.lists.drop" and this will wipe out my lists collection
170
00:14:36,010 --> 00:14:44,060
so that if I say "show collections" again, lists no longer exist. Let's head back to our web page and access
171
00:14:44,180 --> 00:14:46,340
home again.
172
00:14:46,340 --> 00:14:54,860
So that should now be created inside here and "show collections" should now list list and db.lists.
173
00:14:54,890 --> 00:14:59,750
find should now list a single document with name of home.
174
00:14:59,780 --> 00:15:04,860
And if I change that to work and hit enter then
175
00:15:04,910 --> 00:15:10,020
now I should have two documents: one called home and one called work.
176
00:15:10,160 --> 00:15:13,770
But why are they not automatically showing up in here?
177
00:15:14,240 --> 00:15:21,680
Well when we create a new list we fall into this IF block and all we do at the end of it is we just
178
00:15:21,680 --> 00:15:26,100
call list.save and then we're done with it. We're leaving the user hanging right?
179
00:15:26,330 --> 00:15:34,340
So we're going to use our neat trick of using res.redirect and we're going to redirect back to
180
00:15:34,340 --> 00:15:42,090
the current route which remember, is not just the route route but it's /customListName.
181
00:15:42,350 --> 00:15:48,890
But luckily we already have access to that inside this IF statement so we can say redirect to /
182
00:15:49,250 --> 00:15:54,180
and then we're going to concatenate the customListName.
183
00:15:54,230 --> 00:16:02,580
Now if we head back into our website and we tried to create a new list say "School" and hit enter,
184
00:16:02,600 --> 00:16:08,300
you can see we are redirected to that route and we've now got our list showing up here.
19097
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.