Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated:
1
1
00:00:01,300 --> 00:00:04,560
Let's now start implementing the next feature
2
2
00:00:04,560 --> 00:00:06,140
of our application,
3
3
00:00:06,140 --> 00:00:09,143
which is going to be the search functionality.
4
4
00:00:11,190 --> 00:00:15,653
And let's start by taking a look and or flowchart here.
5
5
00:00:16,550 --> 00:00:17,950
And so, again,
6
6
00:00:17,950 --> 00:00:21,960
we already have this part here basically now implemented,
7
7
00:00:21,960 --> 00:00:26,960
and now, we are going to work basically first on this part.
8
8
00:00:27,400 --> 00:00:29,330
So handling the event of a user
9
9
00:00:29,330 --> 00:00:32,050
searching for recipes,
10
10
00:00:32,050 --> 00:00:35,840
then loading the search results and rendering them.
11
11
00:00:35,840 --> 00:00:39,060
So that's going to be this lecture and the next one.
12
12
00:00:39,060 --> 00:00:40,470
And then afterwards,
13
13
00:00:40,470 --> 00:00:43,760
we are going to worry about the pagination.
14
14
00:00:43,760 --> 00:00:47,850
So again, we will now focus on these three parts.
15
15
00:00:47,850 --> 00:00:48,750
And so for that,
16
16
00:00:48,750 --> 00:00:51,840
we need to now implement the model, the view
17
17
00:00:51,840 --> 00:00:55,340
and the controller that binds everything together.
18
18
00:00:55,340 --> 00:00:59,450
And usually, I find it easiest to start with the data.
19
19
00:00:59,450 --> 00:01:01,490
So basically with the model,
20
20
00:01:01,490 --> 00:01:03,190
which means in this case,
21
21
00:01:03,190 --> 00:01:06,340
starting to make some API calls
22
22
00:01:06,340 --> 00:01:08,920
in order to load some search results.
23
23
00:01:08,920 --> 00:01:11,420
And then, once we have that part working,
24
24
00:01:11,420 --> 00:01:13,810
we can then render them on the screen
25
25
00:01:13,810 --> 00:01:16,643
and also care about the actual event.
26
26
00:01:18,370 --> 00:01:22,250
Okay, so let's actually leave that open here at the end
27
27
00:01:22,250 --> 00:01:24,690
and go to our model here,
28
28
00:01:24,690 --> 00:01:28,760
and start implementing the search functionality.
29
29
00:01:28,760 --> 00:01:30,860
So, just like before,
30
30
00:01:30,860 --> 00:01:32,990
we are going to create a function
31
31
00:01:32,990 --> 00:01:34,670
that will be exported
32
32
00:01:34,670 --> 00:01:35,840
so that it can be used
33
33
00:01:35,840 --> 00:01:37,420
by the controller.
34
34
00:01:37,420 --> 00:01:38,610
And this one,
35
35
00:01:38,610 --> 00:01:40,410
I'm gonna call it loadSearchResults.
36
36
00:01:44,730 --> 00:01:49,490
And so, since this one will be performing AJAX calls
37
37
00:01:49,490 --> 00:01:51,823
it's going to be an async function.
38
38
00:01:52,980 --> 00:01:54,850
Now, again dysfunction here
39
39
00:01:54,850 --> 00:01:57,660
is going to be called by the controller.
40
40
00:01:57,660 --> 00:01:59,730
And so, it's going to be the controller
41
41
00:01:59,730 --> 00:02:01,160
who will tell this function
42
42
00:02:01,160 --> 00:02:03,440
what it would actually search for.
43
43
00:02:03,440 --> 00:02:05,870
So basically, it will pass in a query
44
44
00:02:07,180 --> 00:02:09,340
like string, which we can then
45
45
00:02:09,340 --> 00:02:14,340
pluck into our API call, now, right?
46
46
00:02:14,350 --> 00:02:18,293
And here we are going to need a try catch block,
47
47
00:02:21,750 --> 00:02:23,360
and here in the catch block,
48
48
00:02:23,360 --> 00:02:24,963
all we will do is to,
49
49
00:02:26,540 --> 00:02:28,040
basically do the same as here.
50
50
00:02:30,490 --> 00:02:32,860
So, all we're really interested in here
51
51
00:02:32,860 --> 00:02:35,080
is to throw the error again
52
52
00:02:35,080 --> 00:02:36,690
so that eventually,
53
53
00:02:36,690 --> 00:02:39,520
we will be able to use it in the controller.
54
54
00:02:39,520 --> 00:02:41,080
So just like before
55
55
00:02:41,080 --> 00:02:42,360
in the last lecture,
56
56
00:02:42,360 --> 00:02:45,083
where we threw with the error here again.
57
57
00:02:45,920 --> 00:02:48,400
So that part is easy,
58
58
00:02:48,400 --> 00:02:51,520
but now let's actually implement the functionality.
59
59
00:02:51,520 --> 00:02:52,510
And to do that,
60
60
00:02:52,510 --> 00:02:55,833
let's go back to our documentations page.
61
61
00:02:57,350 --> 00:03:01,490
And so, this is how we get all recipes.
62
62
00:03:01,490 --> 00:03:05,860
So making a get request to this path,
63
63
00:03:05,860 --> 00:03:08,660
and then, with the search parameter,
64
64
00:03:08,660 --> 00:03:10,820
and the way we add a parameter,
65
65
00:03:10,820 --> 00:03:13,560
and I think I explained this before
66
66
00:03:13,560 --> 00:03:15,710
is with the question mark,
67
67
00:03:15,710 --> 00:03:17,930
and then search equal,
68
68
00:03:17,930 --> 00:03:20,020
and then, pizza here in our case
69
69
00:03:20,020 --> 00:03:21,973
is actually the search query.
70
70
00:03:22,920 --> 00:03:23,810
And again, for now,
71
71
00:03:23,810 --> 00:03:26,020
don't worry about the key.
72
72
00:03:26,020 --> 00:03:28,120
And we can actually already see
73
73
00:03:28,120 --> 00:03:31,830
what the results will look like here for pizza.
74
74
00:03:31,830 --> 00:03:33,280
And so, basically,
75
75
00:03:33,280 --> 00:03:34,113
this is the URL
76
76
00:03:34,113 --> 00:03:38,660
that we need to call in our AJAX request.
77
77
00:03:38,660 --> 00:03:40,060
So let me actually copy it
78
78
00:03:41,530 --> 00:03:43,280
and let's go back.
79
79
00:03:43,280 --> 00:03:44,113
And so now,
80
80
00:03:44,113 --> 00:03:46,210
we can, just like before,
81
81
00:03:46,210 --> 00:03:48,363
use the get JSON method.
82
82
00:03:49,270 --> 00:03:51,420
And so, that will then fetch the data
83
83
00:03:51,420 --> 00:03:53,640
and also convert it to JSON
84
84
00:03:53,640 --> 00:03:56,663
and create an error if something went wrong.
85
85
00:03:58,320 --> 00:04:00,500
So get JSON returns a promise.
86
86
00:04:00,500 --> 00:04:02,370
And so we await that here
87
87
00:04:02,370 --> 00:04:04,210
and store it into data,
88
88
00:04:04,210 --> 00:04:06,320
just like always.
89
89
00:04:06,320 --> 00:04:07,670
So get JSON
90
90
00:04:07,670 --> 00:04:09,313
and then the URL,
91
91
00:04:10,330 --> 00:04:12,910
and we need a template literal.
92
92
00:04:12,910 --> 00:04:17,910
And so, yeah now we just have to replace everything
93
93
00:04:18,280 --> 00:04:19,980
to make this work.
94
94
00:04:19,980 --> 00:04:20,930
And the first thing
95
95
00:04:20,930 --> 00:04:23,810
is to actually take this here again out,
96
96
00:04:23,810 --> 00:04:26,496
and replace it with this API URL
97
97
00:04:26,496 --> 00:04:31,413
that we already have in our configuration file, right?
98
98
00:04:34,470 --> 00:04:36,593
So API URL,
99
99
00:04:37,740 --> 00:04:39,560
and I think
100
100
00:04:39,560 --> 00:04:42,133
that actually already includes the recipes.
101
101
00:04:44,640 --> 00:04:46,790
Yup, so it's everything.
102
102
00:04:46,790 --> 00:04:51,520
And usually, actually a URL ends with a slash,
103
103
00:04:51,520 --> 00:04:53,710
so it should be like this.
104
104
00:04:53,710 --> 00:04:56,080
And so here, let's take that out,
105
105
00:04:56,080 --> 00:04:58,403
actually, and then here as well.
106
106
00:04:59,810 --> 00:05:02,120
Then here, question mark search
107
107
00:05:02,120 --> 00:05:04,270
and then this one is going to be our query.
108
108
00:05:06,950 --> 00:05:08,340
Now, right?
109
109
00:05:08,340 --> 00:05:11,080
And so, we can then
110
110
00:05:11,080 --> 00:05:12,840
already log that data
111
111
00:05:12,840 --> 00:05:13,990
to the console,
112
112
00:05:13,990 --> 00:05:15,380
to take a look at it
113
113
00:05:15,380 --> 00:05:18,230
before we then manipulate it a little bit.
114
114
00:05:18,230 --> 00:05:19,290
And so right now,
115
115
00:05:19,290 --> 00:05:21,710
this would already be working.
116
116
00:05:21,710 --> 00:05:22,730
And so let's,
117
117
00:05:22,730 --> 00:05:26,200
before we actually write any controller or any view,
118
118
00:05:26,200 --> 00:05:29,490
or we can already call that function here.
119
119
00:05:29,490 --> 00:05:31,153
So load search results,
120
120
00:05:32,380 --> 00:05:33,790
and then let's try it,
121
121
00:05:33,790 --> 00:05:36,280
has always with pizza
122
122
00:05:36,280 --> 00:05:37,573
and see what we get.
123
123
00:05:40,350 --> 00:05:41,803
So that's right here.
124
124
00:05:42,820 --> 00:05:47,230
And indeed, this is the result that we get here.
125
125
00:05:47,230 --> 00:05:49,613
So it's coming from model at line 35.
126
126
00:05:50,480 --> 00:05:52,600
So that's where we were.
127
127
00:05:52,600 --> 00:05:53,433
And so here,
128
128
00:05:53,433 --> 00:05:55,720
is the data that we get back.
129
129
00:05:55,720 --> 00:05:57,370
So we have an object
130
130
00:05:57,370 --> 00:05:59,510
which has a data property,
131
131
00:05:59,510 --> 00:06:02,010
which then has a recipe's property,
132
132
00:06:02,010 --> 00:06:03,523
which is this array.
133
133
00:06:05,550 --> 00:06:08,070
And then, each array contains
134
134
00:06:08,070 --> 00:06:09,470
all of this data
135
135
00:06:09,470 --> 00:06:12,033
about each of the recipes.
136
136
00:06:13,220 --> 00:06:17,060
So, again, this object here is called data
137
137
00:06:17,060 --> 00:06:19,120
then in there, there is data again,
138
138
00:06:19,120 --> 00:06:21,390
and then in there, there is recipes,
139
139
00:06:21,390 --> 00:06:22,807
which is then,
140
140
00:06:22,807 --> 00:06:24,350
the array itself
141
141
00:06:24,350 --> 00:06:25,640
where each of the elements
142
142
00:06:25,640 --> 00:06:26,720
is an object
143
143
00:06:26,720 --> 00:06:28,910
with only some of the data
144
144
00:06:28,910 --> 00:06:30,900
about the recipe.
145
145
00:06:30,900 --> 00:06:33,840
So you see, it's not the complete recipe object,
146
146
00:06:33,840 --> 00:06:35,690
it's only some of the data
147
147
00:06:35,690 --> 00:06:38,160
so that we can actually display it
148
148
00:06:38,160 --> 00:06:40,070
then here in the search results.
149
149
00:06:40,070 --> 00:06:42,290
So without the unnecessary data
150
150
00:06:42,290 --> 00:06:45,140
like ingredients and all that.
151
151
00:06:45,140 --> 00:06:47,900
All right, so let's now take this data
152
152
00:06:47,900 --> 00:06:50,840
and store it into our state.
153
153
00:06:50,840 --> 00:06:53,330
And also, we will want to change,
154
154
00:06:53,330 --> 00:06:54,930
again, this one here,
155
155
00:06:54,930 --> 00:06:56,800
so to image only.
156
156
00:06:56,800 --> 00:07:00,240
And so, we will basically create some new objects
157
157
00:07:00,240 --> 00:07:02,683
based on this data that we receive here.
158
158
00:07:05,090 --> 00:07:06,650
All right.
159
159
00:07:06,650 --> 00:07:11,650
So, we get data.data.recipes.
160
160
00:07:13,970 --> 00:07:15,490
So this is the array.
161
161
00:07:15,490 --> 00:07:18,070
So this is the array of all the objects.
162
162
00:07:18,070 --> 00:07:20,170
And now we want to create a new array
163
163
00:07:20,170 --> 00:07:22,110
which contains the new objects
164
164
00:07:22,110 --> 00:07:24,093
where the property names are different.
165
165
00:07:25,430 --> 00:07:27,223
So, let's map over this,
166
166
00:07:29,210 --> 00:07:30,380
and each element
167
167
00:07:30,380 --> 00:07:32,163
is going to be a recipe.
168
168
00:07:35,070 --> 00:07:38,840
And then here, we will simply return a new object.
169
169
00:07:38,840 --> 00:07:41,850
That's actually copied a code from here
170
170
00:07:41,850 --> 00:07:45,270
because they are the same,
171
171
00:07:45,270 --> 00:07:46,370
at least some of them.
172
172
00:07:47,970 --> 00:07:49,593
So taking all this,
173
173
00:07:50,600 --> 00:07:53,133
int here now, this is only called a rec.
174
174
00:07:55,630 --> 00:07:59,437
Okay, and also we don't have the source URL,
175
175
00:08:00,560 --> 00:08:05,183
we only have ID, title, publisher and image URL, okay.
176
176
00:08:07,160 --> 00:08:10,880
So this will return a new array with the new objects.
177
177
00:08:10,880 --> 00:08:11,713
And so now,
178
178
00:08:11,713 --> 00:08:13,293
where should we store that?
179
179
00:08:14,140 --> 00:08:15,870
Well, as you can guess,
180
180
00:08:15,870 --> 00:08:18,780
we will put it also in our state.
181
181
00:08:18,780 --> 00:08:21,950
So again, the state contains all the data that we need
182
182
00:08:21,950 --> 00:08:24,770
in order to build our application.
183
183
00:08:24,770 --> 00:08:26,430
So let's call this one search
184
184
00:08:27,620 --> 00:08:28,560
and all the data
185
185
00:08:28,560 --> 00:08:29,940
about the application
186
186
00:08:29,940 --> 00:08:31,360
that I just mentioned
187
187
00:08:31,360 --> 00:08:32,400
might as well
188
188
00:08:32,400 --> 00:08:35,203
also include the search query itself.
189
189
00:08:36,420 --> 00:08:38,380
So let's create a new object here
190
190
00:08:38,380 --> 00:08:40,803
and then specify the query,
191
191
00:08:41,930 --> 00:08:43,993
which we start as an empty string.
192
192
00:08:44,830 --> 00:08:48,040
And then, the results, let's say,
193
193
00:08:48,040 --> 00:08:49,880
results, and will start
194
194
00:08:49,880 --> 00:08:51,313
as an empty array.
195
195
00:08:52,620 --> 00:08:54,300
So, basically the state
196
196
00:08:54,300 --> 00:08:56,390
should contain all the data
197
197
00:08:56,390 --> 00:08:58,600
really about the application.
198
198
00:08:58,600 --> 00:08:59,600
Now, in this case,
199
199
00:08:59,600 --> 00:09:03,070
we might not even need the query for now,
200
200
00:09:03,070 --> 00:09:04,500
but it's still a good idea
201
201
00:09:04,500 --> 00:09:07,420
to already store it here in the state,
202
202
00:09:07,420 --> 00:09:08,660
because maybe one day
203
203
00:09:08,660 --> 00:09:09,910
we will need it.
204
204
00:09:09,910 --> 00:09:12,900
And then the data's already there for us.
205
205
00:09:12,900 --> 00:09:16,110
For example, we might want to add some analytics
206
206
00:09:16,110 --> 00:09:17,230
in the future
207
207
00:09:17,230 --> 00:09:20,340
to know which queries are made the most.
208
208
00:09:20,340 --> 00:09:21,680
And so by then,
209
209
00:09:21,680 --> 00:09:23,120
yeah, as I said,
210
210
00:09:23,120 --> 00:09:25,113
that would become useful.
211
211
00:09:26,920 --> 00:09:27,753
Okay.
212
212
00:09:28,640 --> 00:09:31,060
But anyway, let's now store this data
213
213
00:09:31,060 --> 00:09:36,060
in state.search.results, right.
214
214
00:09:41,000 --> 00:09:42,030
And here at the beginning,
215
215
00:09:42,030 --> 00:09:43,800
the very first thing
216
216
00:09:43,800 --> 00:09:45,060
that we're going to do
217
217
00:09:45,060 --> 00:09:48,980
is to state.search.query
218
218
00:09:52,350 --> 00:09:53,513
equal to query.
219
219
00:09:55,860 --> 00:09:56,693
All right.
220
220
00:09:58,190 --> 00:09:59,950
And now, let's quickly
221
221
00:09:59,950 --> 00:10:01,800
just to see if everything worked,
222
222
00:10:01,800 --> 00:10:03,453
log data to the console.
223
223
00:10:05,080 --> 00:10:09,893
So state.search.results.
224
224
00:10:11,406 --> 00:10:12,923
And here we are.
225
225
00:10:14,060 --> 00:10:18,830
So that is exactly the kind of array that we had before.
226
226
00:10:18,830 --> 00:10:20,960
And now the image URL we had before
227
227
00:10:20,960 --> 00:10:22,630
is indeed called image.
228
228
00:10:22,630 --> 00:10:25,593
And so everything has the same format as before.
229
229
00:10:26,640 --> 00:10:28,090
So, we needed to do that
230
230
00:10:28,090 --> 00:10:31,430
because here the image is also called image.
231
231
00:10:31,430 --> 00:10:34,690
And of course, we want everything to have the same names
232
232
00:10:34,690 --> 00:10:38,053
throughout the entire application, all right.
233
233
00:10:38,910 --> 00:10:40,480
So let's get rid of this
234
234
00:10:40,480 --> 00:10:41,340
because of course,
235
235
00:10:41,340 --> 00:10:44,810
we want to call this function in a controller.
236
236
00:10:44,810 --> 00:10:46,400
And so let's go there
237
237
00:10:46,400 --> 00:10:47,440
to the controller
238
238
00:10:48,550 --> 00:10:51,620
and basically create a new function
239
239
00:10:51,620 --> 00:10:54,023
which is going to be like the new controller.
240
240
00:10:55,060 --> 00:10:57,513
So const controlSearchResults.
241
241
00:11:01,000 --> 00:11:01,833
And so this one
242
242
00:11:01,833 --> 00:11:05,460
we'll call the asynchronous function loadSearchResults.
243
243
00:11:05,460 --> 00:11:06,900
And so this one, of course
244
244
00:11:06,900 --> 00:11:11,743
then also need to be an asynchronous function itself.
245
245
00:11:13,824 --> 00:11:16,213
And so, as always try catch,
246
246
00:11:21,050 --> 00:11:24,030
and here for now, let's simply log the error
247
247
00:11:24,030 --> 00:11:25,630
and we will then fix that later.
248
248
00:11:26,700 --> 00:11:29,010
So, here is where we actually
249
249
00:11:29,010 --> 00:11:33,930
will want to call the loadSearchResults that we just built.
250
250
00:11:33,930 --> 00:11:36,933
So that is in model.loadSearchResults.
251
251
00:11:39,710 --> 00:11:40,720
And here we then,
252
252
00:11:40,720 --> 00:11:42,700
we'll need to pass in the query,
253
253
00:11:42,700 --> 00:11:46,420
but for now, let's just do that again manually.
254
254
00:11:46,420 --> 00:11:47,253
And of course,
255
255
00:11:47,253 --> 00:11:49,400
we need to await this,
256
256
00:11:49,400 --> 00:11:52,530
but we do not store any results anywhere
257
257
00:11:52,530 --> 00:11:56,260
because, just like the loadRecipe function,
258
258
00:11:56,260 --> 00:11:59,860
this one also doesn't return anything.
259
259
00:11:59,860 --> 00:12:00,780
All it does
260
260
00:12:00,780 --> 00:12:02,533
is to manipulate the state.
261
261
00:12:03,402 --> 00:12:06,600
And so, then we should be able to do this console.log
262
262
00:12:07,680 --> 00:12:08,740
in the controller
263
263
00:12:08,740 --> 00:12:12,173
and still get access to the results, right?
264
264
00:12:14,070 --> 00:12:16,090
So, let's see.
265
265
00:12:16,090 --> 00:12:19,560
Now, of course, we first have to also call this function.
266
266
00:12:19,560 --> 00:12:20,780
And again, later,
267
267
00:12:20,780 --> 00:12:23,727
we will, of course hook this us up to an event list
268
268
00:12:23,727 --> 00:12:25,880
and our material, let's just
269
269
00:12:27,050 --> 00:12:29,213
call it right away.
270
270
00:12:32,120 --> 00:12:36,733
And now we get status not defined, all right.
271
271
00:12:37,700 --> 00:12:39,060
And that is because,
272
272
00:12:39,060 --> 00:12:44,060
of course it needs to be model.state.search.results.
273
273
00:12:45,740 --> 00:12:49,620
So you see that this is becoming a pretty long chain here
274
274
00:12:49,620 --> 00:12:52,730
but nevermind, that's not a problem at all,
275
275
00:12:52,730 --> 00:12:55,423
because we know exactly what all of this is.
276
276
00:12:56,610 --> 00:12:57,950
And so, now indeed
277
277
00:12:57,950 --> 00:13:02,900
we get back our 59 search results for pizza.
278
278
00:13:02,900 --> 00:13:06,010
But now, instead of only searching for pizza,
279
279
00:13:06,010 --> 00:13:08,970
we actually want to get the query right here
280
280
00:13:08,970 --> 00:13:11,880
from this input field, right?
281
281
00:13:11,880 --> 00:13:14,350
And we also want to start this whole process
282
282
00:13:14,350 --> 00:13:16,573
of loading the search results.
283
283
00:13:17,450 --> 00:13:18,870
So we only want that to happen
284
284
00:13:18,870 --> 00:13:21,680
when this button here is clicked.
285
285
00:13:21,680 --> 00:13:24,950
And so, now let's basically create a view
286
286
00:13:24,950 --> 00:13:27,570
only for this search part here.
287
287
00:13:27,570 --> 00:13:28,840
So right here,
288
288
00:13:28,840 --> 00:13:30,400
we will have a view
289
289
00:13:30,400 --> 00:13:31,800
for this year.
290
290
00:13:31,800 --> 00:13:33,080
So for the search field,
291
291
00:13:33,080 --> 00:13:34,300
and for the button,
292
292
00:13:34,300 --> 00:13:36,140
and then a different view
293
293
00:13:36,140 --> 00:13:39,460
which will actually render the results.
294
294
00:13:39,460 --> 00:13:40,850
So, it's a good idea
295
295
00:13:40,850 --> 00:13:43,630
to keep every view really focused.
296
296
00:13:43,630 --> 00:13:44,840
And so, it's best
297
297
00:13:44,840 --> 00:13:47,180
to just do one for this part,
298
298
00:13:47,180 --> 00:13:49,580
and then one for displaying the results,
299
299
00:13:49,580 --> 00:13:52,000
also because in the user interface,
300
300
00:13:52,000 --> 00:13:55,260
they're actually in kind of different places also.
301
301
00:13:55,260 --> 00:13:58,030
So it makes sense to have a different view.
302
302
00:13:58,030 --> 00:13:59,280
Now this view here
303
303
00:13:59,280 --> 00:14:00,120
is of course
304
304
00:14:00,120 --> 00:14:02,120
not going to render anything,
305
305
00:14:02,120 --> 00:14:03,740
but what it will do
306
306
00:14:03,740 --> 00:14:06,020
is to basically give us the content
307
307
00:14:06,020 --> 00:14:07,963
of this input field.
308
308
00:14:08,820 --> 00:14:10,690
So getting that input data
309
309
00:14:10,690 --> 00:14:11,523
is of course
310
310
00:14:11,523 --> 00:14:13,830
something that has to do with a DOM.
311
311
00:14:13,830 --> 00:14:15,400
And so, it should be in a view
312
312
00:14:15,400 --> 00:14:18,750
and not in a controller, right?
313
313
00:14:18,750 --> 00:14:19,890
So of course,
314
314
00:14:19,890 --> 00:14:21,380
if we wanted to be lazy,
315
315
00:14:21,380 --> 00:14:22,680
we could go ahead
316
316
00:14:22,680 --> 00:14:24,833
and select the element that we want.
317
317
00:14:25,810 --> 00:14:26,880
So it doesn't matter.
318
318
00:14:26,880 --> 00:14:28,240
And then from there,
319
319
00:14:28,240 --> 00:14:30,630
we would simply get the value
320
320
00:14:30,630 --> 00:14:33,113
and then use that as our query.
321
321
00:14:34,600 --> 00:14:36,680
So again, we could do that here,
322
322
00:14:36,680 --> 00:14:39,180
but this is clearly about the DOM.
323
323
00:14:39,180 --> 00:14:41,820
And so, in order to follow our architecture,
324
324
00:14:41,820 --> 00:14:44,810
we will create a new view right now.
325
325
00:14:44,810 --> 00:14:49,810
And this one is going to be called the searchView.js.
326
326
00:14:52,750 --> 00:14:54,610
And just like before,
327
327
00:14:54,610 --> 00:14:59,610
here, we will create a class called searchView
328
328
00:15:03,070 --> 00:15:05,870
and we will then not export that class
329
329
00:15:05,870 --> 00:15:07,520
but export an instance,
330
330
00:15:07,520 --> 00:15:10,573
so an object that was created by this class.
331
331
00:15:11,670 --> 00:15:14,770
So export default new SearchView,
332
332
00:15:15,950 --> 00:15:18,023
and without passing in any data,
333
333
00:15:19,130 --> 00:15:20,540
done just like before,
334
334
00:15:20,540 --> 00:15:22,593
we will have a parent element.
335
335
00:15:24,270 --> 00:15:26,673
So just like in the recipe view,
336
336
00:15:27,640 --> 00:15:28,933
so a parent element,
337
337
00:15:30,150 --> 00:15:32,403
and then we will set that to something,
338
338
00:15:35,030 --> 00:15:38,960
query selector, and now let's see what we get
339
339
00:15:38,960 --> 00:15:40,990
here in the DOM.
340
340
00:15:40,990 --> 00:15:42,293
So in the HTML,
341
341
00:15:43,270 --> 00:15:44,703
so the search,
342
342
00:15:46,940 --> 00:15:48,350
now, it's this one.
343
343
00:15:48,350 --> 00:15:50,730
So we have this entire form,
344
344
00:15:50,730 --> 00:15:52,790
which is called search
345
345
00:15:52,790 --> 00:15:55,050
and which has this input field here
346
346
00:15:55,050 --> 00:15:57,070
and also the button.
347
347
00:15:57,070 --> 00:15:59,700
And so I think that this is the element
348
348
00:15:59,700 --> 00:16:02,010
that makes sense to select.
349
349
00:16:02,010 --> 00:16:07,010
So the one with the class of search, so .search.
350
350
00:16:09,150 --> 00:16:12,500
So this is our parent element here in this case.
351
351
00:16:12,500 --> 00:16:17,080
Now, again, this class is not going to render anything.
352
352
00:16:17,080 --> 00:16:19,820
All we want is to get the query
353
353
00:16:19,820 --> 00:16:22,860
and eventually to also listen for the click event
354
354
00:16:22,860 --> 00:16:24,340
on the button,
355
355
00:16:24,340 --> 00:16:26,720
but let's start with the query here.
356
356
00:16:26,720 --> 00:16:28,540
And so, let's create a method
357
357
00:16:28,540 --> 00:16:32,973
that we will then call from the controller called getQuery.
358
358
00:16:35,490 --> 00:16:36,450
And all this will do
359
359
00:16:36,450 --> 00:16:40,713
is to return this.#parentElement.
360
360
00:16:42,690 --> 00:16:43,523
And so again,
361
361
00:16:43,523 --> 00:16:47,300
that's going to be the search.
362
362
00:16:47,300 --> 00:16:48,270
And then from there,
363
363
00:16:48,270 --> 00:16:51,713
we want to select this input field.
364
364
00:16:53,930 --> 00:16:56,220
So this one with this class.
365
365
00:16:56,220 --> 00:16:59,470
And so let's a select this child element
366
366
00:16:59,470 --> 00:17:01,533
using a querySelector,
367
367
00:17:06,410 --> 00:17:09,913
and then simply get the value of that.
368
368
00:17:11,209 --> 00:17:14,193
Okay, and that's actually it.
369
369
00:17:15,330 --> 00:17:16,380
And again, of course
370
370
00:17:16,380 --> 00:17:19,090
we could have written this exact same code
371
371
00:17:19,090 --> 00:17:20,320
in a controller,
372
372
00:17:20,320 --> 00:17:22,560
but that wouldn't make any sense,
373
373
00:17:22,560 --> 00:17:26,040
because this is not concerned about the DOM at all.
374
374
00:17:26,040 --> 00:17:29,240
So we don't want to have any DOM elements in here.
375
375
00:17:29,240 --> 00:17:32,550
We don't even want to know what the DOM looks like.
376
376
00:17:32,550 --> 00:17:34,730
So actually here we have this,
377
377
00:17:34,730 --> 00:17:36,130
but we don't want this here.
378
378
00:17:37,790 --> 00:17:40,393
Let's get rid of all this clutter here actually.
379
379
00:17:41,890 --> 00:17:44,930
And now, I want to
380
380
00:17:46,800 --> 00:17:51,203
get the searchView here.
381
381
00:17:53,610 --> 00:17:54,753
And then here,
382
382
00:17:56,920 --> 00:17:58,570
we can get that query
383
383
00:17:59,930 --> 00:18:02,600
by saying searchView.getQuery.
384
384
00:18:06,110 --> 00:18:06,943
And of course,
385
385
00:18:06,943 --> 00:18:08,500
there might be no query.
386
386
00:18:08,500 --> 00:18:11,470
And so, let's add another guard clause here.
387
387
00:18:11,470 --> 00:18:13,073
So if there is no query,
388
388
00:18:14,360 --> 00:18:17,050
then return immediately.
389
389
00:18:17,050 --> 00:18:17,883
And so here,
390
390
00:18:17,883 --> 00:18:21,620
we will now no longer look for pizza,
391
391
00:18:21,620 --> 00:18:22,663
but for query.
392
392
00:18:23,690 --> 00:18:24,710
Now, if we run this,
393
393
00:18:24,710 --> 00:18:27,430
then of course there will be no result
394
394
00:18:27,430 --> 00:18:30,200
because, well, right now,
395
395
00:18:30,200 --> 00:18:32,223
there is nothing here to be found.
396
396
00:18:33,290 --> 00:18:34,780
So that controller function
397
397
00:18:34,780 --> 00:18:36,610
runs right in the beginning
398
398
00:18:36,610 --> 00:18:38,830
when the application actually loads.
399
399
00:18:38,830 --> 00:18:40,270
And so by then of course,
400
400
00:18:40,270 --> 00:18:43,150
there is a no value here.
401
401
00:18:43,150 --> 00:18:45,660
And so, in order to actually make this work,
402
402
00:18:45,660 --> 00:18:48,040
we now need to listen for the event
403
403
00:18:48,040 --> 00:18:53,040
of basically clicking this button or submitting this form.
404
404
00:18:53,190 --> 00:18:55,350
And then, only on that event,
405
405
00:18:55,350 --> 00:18:57,300
we want to actually call,
406
406
00:18:57,300 --> 00:18:59,200
this controller function here.
407
407
00:18:59,200 --> 00:19:01,723
So not in the beginning when the script loads.
408
408
00:19:02,610 --> 00:19:04,600
So, in order to do that,
409
409
00:19:04,600 --> 00:19:05,930
we will once again,
410
410
00:19:05,930 --> 00:19:08,950
use the publisher subscriber pattern.
411
411
00:19:08,950 --> 00:19:13,950
So basically exactly what we did here, right?
412
412
00:19:14,580 --> 00:19:16,640
So we will list in for the event
413
413
00:19:16,640 --> 00:19:19,450
in the view right here,
414
414
00:19:19,450 --> 00:19:21,810
and then pass the controller function.
415
415
00:19:21,810 --> 00:19:23,260
So the handler function
416
416
00:19:24,170 --> 00:19:26,593
into the method that we will build here.
417
417
00:19:28,440 --> 00:19:32,400
So this addHandler, a search method here
418
418
00:19:32,400 --> 00:19:33,560
is basically going
419
419
00:19:33,560 --> 00:19:37,770
to be the publisher anti-control search results function
420
420
00:19:37,770 --> 00:19:39,893
is going to be the subscriber.
421
421
00:19:41,690 --> 00:19:46,160
Okay, so hopefully you really understood that pattern
422
422
00:19:46,160 --> 00:19:48,170
that we used before.
423
423
00:19:48,170 --> 00:19:49,003
And so this now,
424
424
00:19:49,003 --> 00:19:50,223
it should be obvious.
425
425
00:19:51,310 --> 00:19:54,160
So, let's take our parent element.
426
426
00:19:54,160 --> 00:19:57,050
So this.#parentElement of course,
427
427
00:19:57,050 --> 00:19:58,030
and then this is where
428
428
00:19:58,030 --> 00:20:00,830
we will actually add the event listener.
429
429
00:20:00,830 --> 00:20:02,680
So not to the button,
430
430
00:20:02,680 --> 00:20:04,750
but really to the entire form
431
431
00:20:04,750 --> 00:20:08,670
because there, we can listen for the submit event.
432
432
00:20:08,670 --> 00:20:10,460
And so then, this will work
433
433
00:20:10,460 --> 00:20:13,320
no matter if the user clicks the submit button
434
434
00:20:13,320 --> 00:20:17,303
or if the user hits Enter while typing the query.
435
435
00:20:18,640 --> 00:20:22,200
Now here, we cannot simply call the handler immediately,
436
436
00:20:22,200 --> 00:20:25,810
because remember, as we did many times before
437
437
00:20:25,810 --> 00:20:27,350
when we submit a form,
438
438
00:20:27,350 --> 00:20:30,680
we need to first prevent the default action,
439
439
00:20:30,680 --> 00:20:33,353
because otherwise the page is going to reload.
440
440
00:20:35,010 --> 00:20:36,897
So, preventDefault.
441
441
00:20:39,890 --> 00:20:41,830
And only after that,
442
442
00:20:41,830 --> 00:20:44,770
we can call the handler function.
443
443
00:20:44,770 --> 00:20:46,770
And, as you already know,
444
444
00:20:46,770 --> 00:20:48,290
this handler function
445
445
00:20:48,290 --> 00:20:51,550
should be the control searchResults function.
446
446
00:20:51,550 --> 00:20:52,940
And so, all we have to do now
447
447
00:20:52,940 --> 00:20:54,900
is to call this method
448
448
00:20:54,900 --> 00:20:57,293
and pass in that function.
449
449
00:20:58,590 --> 00:21:00,890
So, let's do that here right at the beginning.
450
450
00:21:01,890 --> 00:21:03,123
So searchView.addHandlerSearch.
451
451
00:21:07,040 --> 00:21:09,660
So you'll see that I'm always going to use
452
452
00:21:09,660 --> 00:21:11,590
this name here of addHandler,
453
453
00:21:13,840 --> 00:21:16,740
and then we pass in the controller function
454
454
00:21:17,740 --> 00:21:19,430
and that's it.
455
455
00:21:19,430 --> 00:21:21,833
So now it should actually already work.
456
456
00:21:23,460 --> 00:21:24,780
So let's see.
457
457
00:21:24,780 --> 00:21:27,680
And actually, let's clear up all this clutter
458
458
00:21:27,680 --> 00:21:28,623
here a little bit.
459
459
00:21:29,550 --> 00:21:32,270
Okay, so this console.log,
460
460
00:21:32,270 --> 00:21:35,413
and there's also some here in the recipe view.
461
461
00:21:36,380 --> 00:21:37,423
So that's this one.
462
462
00:21:40,470 --> 00:21:43,400
Okay, so that's again, try pizza
463
463
00:21:44,470 --> 00:21:48,033
and yeah, beautiful, it worked.
464
464
00:21:49,240 --> 00:21:50,930
So we get
465
465
00:21:50,930 --> 00:21:53,890
this data first here coming from the model,
466
466
00:21:53,890 --> 00:21:55,630
and then also in a controller,
467
467
00:21:55,630 --> 00:21:57,140
we also logged it.
468
468
00:21:57,140 --> 00:22:01,290
And so here we have the exact same 59 data
469
469
00:22:01,290 --> 00:22:02,293
that we had before.
470
470
00:22:03,130 --> 00:22:05,060
Let's try something else now,
471
471
00:22:05,060 --> 00:22:06,403
avocado, let's say,
472
472
00:22:08,020 --> 00:22:09,343
so I hit Enter,
473
473
00:22:10,910 --> 00:22:15,320
and, so this time we got 39 search results
474
474
00:22:16,650 --> 00:22:17,483
and you see,
475
475
00:22:17,483 --> 00:22:20,250
all of them basically have avocado
476
476
00:22:20,250 --> 00:22:22,400
right there in the title,
477
477
00:22:22,400 --> 00:22:23,650
it's really beautiful
478
478
00:22:23,650 --> 00:22:25,833
that it already works this great.
479
479
00:22:26,670 --> 00:22:28,800
Now just one small detail,
480
480
00:22:28,800 --> 00:22:30,460
is that, after we search,
481
481
00:22:30,460 --> 00:22:33,450
we should probably clear out this field.
482
482
00:22:33,450 --> 00:22:36,873
So let's add another small method for that in the view.
483
483
00:22:37,960 --> 00:22:40,053
So, and this one here,
484
484
00:22:42,030 --> 00:22:42,933
so clearInput,
485
485
00:22:44,900 --> 00:22:46,590
and once again,
486
486
00:22:46,590 --> 00:22:51,420
having it nicely encapsulated inside of the searchView.
487
487
00:22:51,420 --> 00:22:54,850
So again, this could simply be also in a controller,
488
488
00:22:54,850 --> 00:22:57,700
because, it's really just one line of code,
489
489
00:22:57,700 --> 00:23:00,750
but we want to keep everything separated.
490
490
00:23:00,750 --> 00:23:03,510
This will make it so much easier to add features
491
491
00:23:03,510 --> 00:23:05,110
in the future.
492
492
00:23:05,110 --> 00:23:06,660
And it's really so much better.
493
493
00:23:08,060 --> 00:23:12,663
So, all we do is to set this to empty and that's it.
494
494
00:23:14,050 --> 00:23:16,950
All right, let's try it one more time.
495
495
00:23:16,950 --> 00:23:18,543
Let's say pasta this time.
496
496
00:23:19,860 --> 00:23:24,860
Ah, of course we never called DOM method here anywhere.
497
497
00:23:25,090 --> 00:23:27,383
So we need to do that in the controller.
498
498
00:23:28,760 --> 00:23:31,603
And let's actually add some more comments here.
499
499
00:23:34,100 --> 00:23:35,943
So Get search query.
500
500
00:23:38,290 --> 00:23:42,950
And the code itself is actually pretty self explanatory.
501
501
00:23:42,950 --> 00:23:45,010
And so many developers will tell you
502
502
00:23:45,010 --> 00:23:46,760
you should not comment it,
503
503
00:23:46,760 --> 00:23:47,593
but I think
504
504
00:23:47,593 --> 00:23:50,740
that this is actually very helpful when you read the code
505
505
00:23:50,740 --> 00:23:53,003
in like one or two years from now.
506
506
00:23:54,960 --> 00:23:59,960
So, I would advise you to always write comments like this
507
507
00:24:00,120 --> 00:24:03,110
even if your code seems pretty obvious,
508
508
00:24:03,110 --> 00:24:04,540
especially when it's like
509
509
00:24:04,540 --> 00:24:07,103
a bigger list of instructions like this,
510
510
00:24:08,770 --> 00:24:11,870
so Render results.
511
511
00:24:11,870 --> 00:24:15,483
So right now our rendering is only a console.log.
512
512
00:24:16,520 --> 00:24:19,150
But here, when we get a search query,
513
513
00:24:19,150 --> 00:24:20,580
we can actually then
514
514
00:24:20,580 --> 00:24:24,030
immediately also clear it afterwards.
515
515
00:24:24,030 --> 00:24:25,880
Or in fact,
516
516
00:24:25,880 --> 00:24:28,860
in order to keep this controller even simpler,
517
517
00:24:28,860 --> 00:24:29,780
we can do that
518
518
00:24:29,780 --> 00:24:32,340
right in the getQuery method.
519
519
00:24:32,340 --> 00:24:35,690
So, let's go back here,
520
520
00:24:35,690 --> 00:24:37,720
and now we can make this private,
521
521
00:24:37,720 --> 00:24:40,223
so we're not going to use it outside.
522
522
00:24:41,170 --> 00:24:43,640
And then let's actually call it here.
523
523
00:24:43,640 --> 00:24:45,383
So this.#clearInput.
524
524
00:24:51,601 --> 00:24:52,434
And then of course,
525
525
00:24:52,434 --> 00:24:55,923
we first need to store this somewhere here.
526
526
00:25:00,500 --> 00:25:01,980
So we get the query,
527
527
00:25:01,980 --> 00:25:03,340
then we clear the field
528
528
00:25:04,220 --> 00:25:06,173
and then we return the query.
529
529
00:25:08,150 --> 00:25:10,963
All right, so that should now work.
530
530
00:25:13,674 --> 00:25:16,280
So pasta and clears the field,
531
531
00:25:16,280 --> 00:25:21,053
and gives us or 45 results down here about pasta.
532
532
00:25:22,050 --> 00:25:25,810
Great, so that works just fine.
533
533
00:25:25,810 --> 00:25:27,500
And so, all there's left to do
534
534
00:25:27,500 --> 00:25:31,110
is to now implement actually the view.
535
535
00:25:31,110 --> 00:25:33,290
So the second view basically.
536
536
00:25:33,290 --> 00:25:34,670
So the one
537
537
00:25:34,670 --> 00:25:35,690
that is responsible
538
538
00:25:35,690 --> 00:25:37,960
for then rendering all the results
539
539
00:25:37,960 --> 00:25:39,800
here in this sidebar.
540
540
00:25:39,800 --> 00:25:42,400
And so that's going to be a little bit of work.
541
541
00:25:42,400 --> 00:25:44,633
So let's leave that for the next video.
43053
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.