WEBVTT

1
00:00:01.300 --> 00:00:04.560
<v Jonas>Let's now start implementing the next feature</v>

2
00:00:04.560 --> 00:00:06.140
of our application,

3
00:00:06.140 --> 00:00:09.143
which is going to be the search functionality.

4
00:00:11.190 --> 00:00:15.653
And let's start by taking a look and or flowchart here.

5
00:00:16.550 --> 00:00:17.950
And so, again,

6
00:00:17.950 --> 00:00:21.960
we already have this part here basically now implemented,

7
00:00:21.960 --> 00:00:26.960
and now, we are going to work basically first on this part.

8
00:00:27.400 --> 00:00:29.330
So handling the event of a user

9
00:00:29.330 --> 00:00:32.050
searching for recipes,

10
00:00:32.050 --> 00:00:35.840
then loading the search results and rendering them.

11
00:00:35.840 --> 00:00:39.060
So that's going to be this lecture and the next one.

12
00:00:39.060 --> 00:00:40.470
And then afterwards,

13
00:00:40.470 --> 00:00:43.760
we are going to worry about the pagination.

14
00:00:43.760 --> 00:00:47.850
So again, we will now focus on these three parts.

15
00:00:47.850 --> 00:00:48.750
And so for that,

16
00:00:48.750 --> 00:00:51.840
we need to now implement the model, the view

17
00:00:51.840 --> 00:00:55.340
and the controller that binds everything together.

18
00:00:55.340 --> 00:00:59.450
And usually, I find it easiest to start with the data.

19
00:00:59.450 --> 00:01:01.490
So basically with the model,

20
00:01:01.490 --> 00:01:03.190
which means in this case,

21
00:01:03.190 --> 00:01:06.340
starting to make some API calls

22
00:01:06.340 --> 00:01:08.920
in order to load some search results.

23
00:01:08.920 --> 00:01:11.420
And then, once we have that part working,

24
00:01:11.420 --> 00:01:13.810
we can then render them on the screen

25
00:01:13.810 --> 00:01:16.643
and also care about the actual event.

26
00:01:18.370 --> 00:01:22.250
Okay, so let's actually leave that open here at the end

27
00:01:22.250 --> 00:01:24.690
and go to our model here,

28
00:01:24.690 --> 00:01:28.760
and start implementing the search functionality.

29
00:01:28.760 --> 00:01:30.860
So, just like before,

30
00:01:30.860 --> 00:01:32.990
we are going to create a function

31
00:01:32.990 --> 00:01:34.670
that will be exported

32
00:01:34.670 --> 00:01:35.840
so that it can be used

33
00:01:35.840 --> 00:01:37.420
by the controller.

34
00:01:37.420 --> 00:01:38.610
And this one,

35
00:01:38.610 --> 00:01:40.410
I'm gonna call it loadSearchResults.

36
00:01:44.730 --> 00:01:49.490
And so, since this one will be performing AJAX calls

37
00:01:49.490 --> 00:01:51.823
it's going to be an async function.

38
00:01:52.980 --> 00:01:54.850
Now, again dysfunction here

39
00:01:54.850 --> 00:01:57.660
is going to be called by the controller.

40
00:01:57.660 --> 00:01:59.730
And so, it's going to be the controller

41
00:01:59.730 --> 00:02:01.160
who will tell this function

42
00:02:01.160 --> 00:02:03.440
what it would actually search for.

43
00:02:03.440 --> 00:02:05.870
So basically, it will pass in a query

44
00:02:07.180 --> 00:02:09.340
like string, which we can then

45
00:02:09.340 --> 00:02:14.340
pluck into our API call, now, right?

46
00:02:14.350 --> 00:02:18.293
And here we are going to need a try catch block,

47
00:02:21.750 --> 00:02:23.360
and here in the catch block,

48
00:02:23.360 --> 00:02:24.963
all we will do is to,

49
00:02:26.540 --> 00:02:28.040
basically do the same as here.

50
00:02:30.490 --> 00:02:32.860
So, all we're really interested in here

51
00:02:32.860 --> 00:02:35.080
is to throw the error again

52
00:02:35.080 --> 00:02:36.690
so that eventually,

53
00:02:36.690 --> 00:02:39.520
we will be able to use it in the controller.

54
00:02:39.520 --> 00:02:41.080
So just like before

55
00:02:41.080 --> 00:02:42.360
in the last lecture,

56
00:02:42.360 --> 00:02:45.083
where we threw with the error here again.

57
00:02:45.920 --> 00:02:48.400
So that part is easy,

58
00:02:48.400 --> 00:02:51.520
but now let's actually implement the functionality.

59
00:02:51.520 --> 00:02:52.510
And to do that,

60
00:02:52.510 --> 00:02:55.833
let's go back to our documentations page.

61
00:02:57.350 --> 00:03:01.490
And so, this is how we get all recipes.

62
00:03:01.490 --> 00:03:05.860
So making a get request to this path,

63
00:03:05.860 --> 00:03:08.660
and then, with the search parameter,

64
00:03:08.660 --> 00:03:10.820
and the way we add a parameter,

65
00:03:10.820 --> 00:03:13.560
and I think I explained this before

66
00:03:13.560 --> 00:03:15.710
is with the question mark,

67
00:03:15.710 --> 00:03:17.930
and then search equal,

68
00:03:17.930 --> 00:03:20.020
and then, pizza here in our case

69
00:03:20.020 --> 00:03:21.973
is actually the search query.

70
00:03:22.920 --> 00:03:23.810
And again, for now,

71
00:03:23.810 --> 00:03:26.020
don't worry about the key.

72
00:03:26.020 --> 00:03:28.120
And we can actually already see

73
00:03:28.120 --> 00:03:31.830
what the results will look like here for pizza.

74
00:03:31.830 --> 00:03:33.280
And so, basically,

75
00:03:33.280 --> 00:03:34.113
this is the URL

76
00:03:34.113 --> 00:03:38.660
that we need to call in our AJAX request.

77
00:03:38.660 --> 00:03:40.060
So let me actually copy it

78
00:03:41.530 --> 00:03:43.280
and let's go back.

79
00:03:43.280 --> 00:03:44.113
And so now,

80
00:03:44.113 --> 00:03:46.210
we can, just like before,

81
00:03:46.210 --> 00:03:48.363
use the get JSON method.

82
00:03:49.270 --> 00:03:51.420
And so, that will then fetch the data

83
00:03:51.420 --> 00:03:53.640
and also convert it to JSON

84
00:03:53.640 --> 00:03:56.663
and create an error if something went wrong.

85
00:03:58.320 --> 00:04:00.500
So get JSON returns a promise.

86
00:04:00.500 --> 00:04:02.370
And so we await that here

87
00:04:02.370 --> 00:04:04.210
and store it into data,

88
00:04:04.210 --> 00:04:06.320
just like always.

89
00:04:06.320 --> 00:04:07.670
So get JSON

90
00:04:07.670 --> 00:04:09.313
and then the URL,

91
00:04:10.330 --> 00:04:12.910
and we need a template literal.

92
00:04:12.910 --> 00:04:17.910
And so, yeah now we just have to replace everything

93
00:04:18.280 --> 00:04:19.980
to make this work.

94
00:04:19.980 --> 00:04:20.930
And the first thing

95
00:04:20.930 --> 00:04:23.810
is to actually take this here again out,

96
00:04:23.810 --> 00:04:26.496
and replace it with this API URL

97
00:04:26.496 --> 00:04:31.413
that we already have in our configuration file, right?

98
00:04:34.470 --> 00:04:36.593
So API URL,

99
00:04:37.740 --> 00:04:39.560
and I think

100
00:04:39.560 --> 00:04:42.133
that actually already includes the recipes.

101
00:04:44.640 --> 00:04:46.790
Yup, so it's everything.

102
00:04:46.790 --> 00:04:51.520
And usually, actually a URL ends with a slash,

103
00:04:51.520 --> 00:04:53.710
so it should be like this.

104
00:04:53.710 --> 00:04:56.080
And so here, let's take that out,

105
00:04:56.080 --> 00:04:58.403
actually, and then here as well.

106
00:04:59.810 --> 00:05:02.120
Then here, question mark search

107
00:05:02.120 --> 00:05:04.270
and then this one is going to be our query.

108
00:05:06.950 --> 00:05:08.340
Now, right?

109
00:05:08.340 --> 00:05:11.080
And so, we can then

110
00:05:11.080 --> 00:05:12.840
already log that data

111
00:05:12.840 --> 00:05:13.990
to the console,

112
00:05:13.990 --> 00:05:15.380
to take a look at it

113
00:05:15.380 --> 00:05:18.230
before we then manipulate it a little bit.

114
00:05:18.230 --> 00:05:19.290
And so right now,

115
00:05:19.290 --> 00:05:21.710
this would already be working.

116
00:05:21.710 --> 00:05:22.730
And so let's,

117
00:05:22.730 --> 00:05:26.200
before we actually write any controller or any view,

118
00:05:26.200 --> 00:05:29.490
or we can already call that function here.

119
00:05:29.490 --> 00:05:31.153
So load search results,

120
00:05:32.380 --> 00:05:33.790
and then let's try it,

121
00:05:33.790 --> 00:05:36.280
has always with pizza

122
00:05:36.280 --> 00:05:37.573
and see what we get.

123
00:05:40.350 --> 00:05:41.803
So that's right here.

124
00:05:42.820 --> 00:05:47.230
And indeed, this is the result that we get here.

125
00:05:47.230 --> 00:05:49.613
So it's coming from model at line 35.

126
00:05:50.480 --> 00:05:52.600
So that's where we were.

127
00:05:52.600 --> 00:05:53.433
And so here,

128
00:05:53.433 --> 00:05:55.720
is the data that we get back.

129
00:05:55.720 --> 00:05:57.370
So we have an object

130
00:05:57.370 --> 00:05:59.510
which has a data property,

131
00:05:59.510 --> 00:06:02.010
which then has a recipe's property,

132
00:06:02.010 --> 00:06:03.523
which is this array.

133
00:06:05.550 --> 00:06:08.070
And then, each array contains

134
00:06:08.070 --> 00:06:09.470
all of this data

135
00:06:09.470 --> 00:06:12.033
about each of the recipes.

136
00:06:13.220 --> 00:06:17.060
So, again, this object here is called data

137
00:06:17.060 --> 00:06:19.120
then in there, there is data again,

138
00:06:19.120 --> 00:06:21.390
and then in there, there is recipes,

139
00:06:21.390 --> 00:06:22.807
which is then,

140
00:06:22.807 --> 00:06:24.350
the array itself

141
00:06:24.350 --> 00:06:25.640
where each of the elements

142
00:06:25.640 --> 00:06:26.720
is an object

143
00:06:26.720 --> 00:06:28.910
with only some of the data

144
00:06:28.910 --> 00:06:30.900
about the recipe.

145
00:06:30.900 --> 00:06:33.840
So you see, it's not the complete recipe object,

146
00:06:33.840 --> 00:06:35.690
it's only some of the data

147
00:06:35.690 --> 00:06:38.160
so that we can actually display it

148
00:06:38.160 --> 00:06:40.070
then here in the search results.

149
00:06:40.070 --> 00:06:42.290
So without the unnecessary data

150
00:06:42.290 --> 00:06:45.140
like ingredients and all that.

151
00:06:45.140 --> 00:06:47.900
All right, so let's now take this data

152
00:06:47.900 --> 00:06:50.840
and store it into our state.

153
00:06:50.840 --> 00:06:53.330
And also, we will want to change,

154
00:06:53.330 --> 00:06:54.930
again, this one here,

155
00:06:54.930 --> 00:06:56.800
so to image only.

156
00:06:56.800 --> 00:07:00.240
And so, we will basically create some new objects

157
00:07:00.240 --> 00:07:02.683
based on this data that we receive here.

158
00:07:05.090 --> 00:07:06.650
All right.

159
00:07:06.650 --> 00:07:11.650
So, we get data.data.recipes.

160
00:07:13.970 --> 00:07:15.490
So this is the array.

161
00:07:15.490 --> 00:07:18.070
So this is the array of all the objects.

162
00:07:18.070 --> 00:07:20.170
And now we want to create a new array

163
00:07:20.170 --> 00:07:22.110
which contains the new objects

164
00:07:22.110 --> 00:07:24.093
where the property names are different.

165
00:07:25.430 --> 00:07:27.223
So, let's map over this,

166
00:07:29.210 --> 00:07:30.380
and each element

167
00:07:30.380 --> 00:07:32.163
is going to be a recipe.

168
00:07:35.070 --> 00:07:38.840
And then here, we will simply return a new object.

169
00:07:38.840 --> 00:07:41.850
That's actually copied a code from here

170
00:07:41.850 --> 00:07:45.270
because they are the same,

171
00:07:45.270 --> 00:07:46.370
at least some of them.

172
00:07:47.970 --> 00:07:49.593
So taking all this,

173
00:07:50.600 --> 00:07:53.133
int here now, this is only called a rec.

174
00:07:55.630 --> 00:07:59.437
Okay, and also we don't have the source URL,

175
00:08:00.560 --> 00:08:05.183
we only have ID, title, publisher and image URL, okay.

176
00:08:07.160 --> 00:08:10.880
So this will return a new array with the new objects.

177
00:08:10.880 --> 00:08:11.713
And so now,

178
00:08:11.713 --> 00:08:13.293
where should we store that?

179
00:08:14.140 --> 00:08:15.870
Well, as you can guess,

180
00:08:15.870 --> 00:08:18.780
we will put it also in our state.

181
00:08:18.780 --> 00:08:21.950
So again, the state contains all the data that we need

182
00:08:21.950 --> 00:08:24.770
in order to build our application.

183
00:08:24.770 --> 00:08:26.430
So let's call this one search

184
00:08:27.620 --> 00:08:28.560
and all the data

185
00:08:28.560 --> 00:08:29.940
about the application

186
00:08:29.940 --> 00:08:31.360
that I just mentioned

187
00:08:31.360 --> 00:08:32.400
might as well

188
00:08:32.400 --> 00:08:35.203
also include the search query itself.

189
00:08:36.420 --> 00:08:38.380
So let's create a new object here

190
00:08:38.380 --> 00:08:40.803
and then specify the query,

191
00:08:41.930 --> 00:08:43.993
which we start as an empty string.

192
00:08:44.830 --> 00:08:48.040
And then, the results, let's say,

193
00:08:48.040 --> 00:08:49.880
results, and will start

194
00:08:49.880 --> 00:08:51.313
as an empty array.

195
00:08:52.620 --> 00:08:54.300
So, basically the state

196
00:08:54.300 --> 00:08:56.390
should contain all the data

197
00:08:56.390 --> 00:08:58.600
really about the application.

198
00:08:58.600 --> 00:08:59.600
Now, in this case,

199
00:08:59.600 --> 00:09:03.070
we might not even need the query for now,

200
00:09:03.070 --> 00:09:04.500
but it's still a good idea

201
00:09:04.500 --> 00:09:07.420
to already store it here in the state,

202
00:09:07.420 --> 00:09:08.660
because maybe one day

203
00:09:08.660 --> 00:09:09.910
we will need it.

204
00:09:09.910 --> 00:09:12.900
And then the data's already there for us.

205
00:09:12.900 --> 00:09:16.110
For example, we might want to add some analytics

206
00:09:16.110 --> 00:09:17.230
in the future

207
00:09:17.230 --> 00:09:20.340
to know which queries are made the most.

208
00:09:20.340 --> 00:09:21.680
And so by then,

209
00:09:21.680 --> 00:09:23.120
yeah, as I said,

210
00:09:23.120 --> 00:09:25.113
that would become useful.

211
00:09:26.920 --> 00:09:27.753
Okay.

212
00:09:28.640 --> 00:09:31.060
But anyway, let's now store this data

213
00:09:31.060 --> 00:09:36.060
in state.search.results, right.

214
00:09:41.000 --> 00:09:42.030
And here at the beginning,

215
00:09:42.030 --> 00:09:43.800
the very first thing

216
00:09:43.800 --> 00:09:45.060
that we're going to do

217
00:09:45.060 --> 00:09:48.980
is to state.search.query

218
00:09:52.350 --> 00:09:53.513
equal to query.

219
00:09:55.860 --> 00:09:56.693
All right.

220
00:09:58.190 --> 00:09:59.950
And now, let's quickly

221
00:09:59.950 --> 00:10:01.800
just to see if everything worked,

222
00:10:01.800 --> 00:10:03.453
log data to the console.

223
00:10:05.080 --> 00:10:09.893
So state.search.results.

224
00:10:11.406 --> 00:10:12.923
And here we are.

225
00:10:14.060 --> 00:10:18.830
So that is exactly the kind of array that we had before.

226
00:10:18.830 --> 00:10:20.960
And now the image URL we had before

227
00:10:20.960 --> 00:10:22.630
is indeed called image.

228
00:10:22.630 --> 00:10:25.593
And so everything has the same format as before.

229
00:10:26.640 --> 00:10:28.090
So, we needed to do that

230
00:10:28.090 --> 00:10:31.430
because here the image is also called image.

231
00:10:31.430 --> 00:10:34.690
And of course, we want everything to have the same names

232
00:10:34.690 --> 00:10:38.053
throughout the entire application, all right.

233
00:10:38.910 --> 00:10:40.480
So let's get rid of this

234
00:10:40.480 --> 00:10:41.340
because of course,

235
00:10:41.340 --> 00:10:44.810
we want to call this function in a controller.

236
00:10:44.810 --> 00:10:46.400
And so let's go there

237
00:10:46.400 --> 00:10:47.440
to the controller

238
00:10:48.550 --> 00:10:51.620
and basically create a new function

239
00:10:51.620 --> 00:10:54.023
which is going to be like the new controller.

240
00:10:55.060 --> 00:10:57.513
So const controlSearchResults.

241
00:11:01.000 --> 00:11:01.833
And so this one

242
00:11:01.833 --> 00:11:05.460
we'll call the asynchronous function loadSearchResults.

243
00:11:05.460 --> 00:11:06.900
And so this one, of course

244
00:11:06.900 --> 00:11:11.743
then also need to be an asynchronous function itself.

245
00:11:13.824 --> 00:11:16.213
And so, as always try catch,

246
00:11:21.050 --> 00:11:24.030
and here for now, let's simply log the error

247
00:11:24.030 --> 00:11:25.630
and we will then fix that later.

248
00:11:26.700 --> 00:11:29.010
So, here is where we actually

249
00:11:29.010 --> 00:11:33.930
will want to call the loadSearchResults that we just built.

250
00:11:33.930 --> 00:11:36.933
So that is in model.loadSearchResults.

251
00:11:39.710 --> 00:11:40.720
And here we then,

252
00:11:40.720 --> 00:11:42.700
we'll need to pass in the query,

253
00:11:42.700 --> 00:11:46.420
but for now, let's just do that again manually.

254
00:11:46.420 --> 00:11:47.253
And of course,

255
00:11:47.253 --> 00:11:49.400
we need to await this,

256
00:11:49.400 --> 00:11:52.530
but we do not store any results anywhere

257
00:11:52.530 --> 00:11:56.260
because, just like the loadRecipe function,

258
00:11:56.260 --> 00:11:59.860
this one also doesn't return anything.

259
00:11:59.860 --> 00:12:00.780
All it does

260
00:12:00.780 --> 00:12:02.533
is to manipulate the state.

261
00:12:03.402 --> 00:12:06.600
And so, then we should be able to do this console.log

262
00:12:07.680 --> 00:12:08.740
in the controller

263
00:12:08.740 --> 00:12:12.173
and still get access to the results, right?

264
00:12:14.070 --> 00:12:16.090
So, let's see.

265
00:12:16.090 --> 00:12:19.560
Now, of course, we first have to also call this function.

266
00:12:19.560 --> 00:12:20.780
And again, later,

267
00:12:20.780 --> 00:12:23.727
we will, of course hook this us up to an event list

268
00:12:23.727 --> 00:12:25.880
and our material, let's just

269
00:12:27.050 --> 00:12:29.213
call it right away.

270
00:12:32.120 --> 00:12:36.733
And now we get status not defined, all right.

271
00:12:37.700 --> 00:12:39.060
And that is because,

272
00:12:39.060 --> 00:12:44.060
of course it needs to be model.state.search.results.

273
00:12:45.740 --> 00:12:49.620
So you see that this is becoming a pretty long chain here

274
00:12:49.620 --> 00:12:52.730
but nevermind, that's not a problem at all,

275
00:12:52.730 --> 00:12:55.423
because we know exactly what all of this is.

276
00:12:56.610 --> 00:12:57.950
And so, now indeed

277
00:12:57.950 --> 00:13:02.900
we get back our 59 search results for pizza.

278
00:13:02.900 --> 00:13:06.010
But now, instead of only searching for pizza,

279
00:13:06.010 --> 00:13:08.970
we actually want to get the query right here

280
00:13:08.970 --> 00:13:11.880
from this input field, right?

281
00:13:11.880 --> 00:13:14.350
And we also want to start this whole process

282
00:13:14.350 --> 00:13:16.573
of loading the search results.

283
00:13:17.450 --> 00:13:18.870
So we only want that to happen

284
00:13:18.870 --> 00:13:21.680
when this button here is clicked.

285
00:13:21.680 --> 00:13:24.950
And so, now let's basically create a view

286
00:13:24.950 --> 00:13:27.570
only for this search part here.

287
00:13:27.570 --> 00:13:28.840
So right here,

288
00:13:28.840 --> 00:13:30.400
we will have a view

289
00:13:30.400 --> 00:13:31.800
for this year.

290
00:13:31.800 --> 00:13:33.080
So for the search field,

291
00:13:33.080 --> 00:13:34.300
and for the button,

292
00:13:34.300 --> 00:13:36.140
and then a different view

293
00:13:36.140 --> 00:13:39.460
which will actually render the results.

294
00:13:39.460 --> 00:13:40.850
So, it's a good idea

295
00:13:40.850 --> 00:13:43.630
to keep every view really focused.

296
00:13:43.630 --> 00:13:44.840
And so, it's best

297
00:13:44.840 --> 00:13:47.180
to just do one for this part,

298
00:13:47.180 --> 00:13:49.580
and then one for displaying the results,

299
00:13:49.580 --> 00:13:52.000
also because in the user interface,

300
00:13:52.000 --> 00:13:55.260
they're actually in kind of different places also.

301
00:13:55.260 --> 00:13:58.030
So it makes sense to have a different view.

302
00:13:58.030 --> 00:13:59.280
Now this view here

303
00:13:59.280 --> 00:14:00.120
is of course

304
00:14:00.120 --> 00:14:02.120
not going to render anything,

305
00:14:02.120 --> 00:14:03.740
but what it will do

306
00:14:03.740 --> 00:14:06.020
is to basically give us the content

307
00:14:06.020 --> 00:14:07.963
of this input field.

308
00:14:08.820 --> 00:14:10.690
So getting that input data

309
00:14:10.690 --> 00:14:11.523
is of course

310
00:14:11.523 --> 00:14:13.830
something that has to do with a DOM.

311
00:14:13.830 --> 00:14:15.400
And so, it should be in a view

312
00:14:15.400 --> 00:14:18.750
and not in a controller, right?

313
00:14:18.750 --> 00:14:19.890
So of course,

314
00:14:19.890 --> 00:14:21.380
if we wanted to be lazy,

315
00:14:21.380 --> 00:14:22.680
we could go ahead

316
00:14:22.680 --> 00:14:24.833
and select the element that we want.

317
00:14:25.810 --> 00:14:26.880
So it doesn't matter.

318
00:14:26.880 --> 00:14:28.240
And then from there,

319
00:14:28.240 --> 00:14:30.630
we would simply get the value

320
00:14:30.630 --> 00:14:33.113
and then use that as our query.

321
00:14:34.600 --> 00:14:36.680
So again, we could do that here,

322
00:14:36.680 --> 00:14:39.180
but this is clearly about the DOM.

323
00:14:39.180 --> 00:14:41.820
And so, in order to follow our architecture,

324
00:14:41.820 --> 00:14:44.810
we will create a new view right now.

325
00:14:44.810 --> 00:14:49.810
And this one is going to be called the searchView.js.

326
00:14:52.750 --> 00:14:54.610
And just like before,

327
00:14:54.610 --> 00:14:59.610
here, we will create a class called searchView

328
00:15:03.070 --> 00:15:05.870
and we will then not export that class

329
00:15:05.870 --> 00:15:07.520
but export an instance,

330
00:15:07.520 --> 00:15:10.573
so an object that was created by this class.

331
00:15:11.670 --> 00:15:14.770
So export default new SearchView,

332
00:15:15.950 --> 00:15:18.023
and without passing in any data,

333
00:15:19.130 --> 00:15:20.540
done just like before,

334
00:15:20.540 --> 00:15:22.593
we will have a parent element.

335
00:15:24.270 --> 00:15:26.673
So just like in the recipe view,

336
00:15:27.640 --> 00:15:28.933
so a parent element,

337
00:15:30.150 --> 00:15:32.403
and then we will set that to something,

338
00:15:35.030 --> 00:15:38.960
query selector, and now let's see what we get

339
00:15:38.960 --> 00:15:40.990
here in the DOM.

340
00:15:40.990 --> 00:15:42.293
So in the HTML,

341
00:15:43.270 --> 00:15:44.703
so the search,

342
00:15:46.940 --> 00:15:48.350
now, it's this one.

343
00:15:48.350 --> 00:15:50.730
So we have this entire form,

344
00:15:50.730 --> 00:15:52.790
which is called search

345
00:15:52.790 --> 00:15:55.050
and which has this input field here

346
00:15:55.050 --> 00:15:57.070
and also the button.

347
00:15:57.070 --> 00:15:59.700
And so I think that this is the element

348
00:15:59.700 --> 00:16:02.010
that makes sense to select.

349
00:16:02.010 --> 00:16:07.010
So the one with the class of search, so .search.

350
00:16:09.150 --> 00:16:12.500
So this is our parent element here in this case.

351
00:16:12.500 --> 00:16:17.080
Now, again, this class is not going to render anything.

352
00:16:17.080 --> 00:16:19.820
All we want is to get the query

353
00:16:19.820 --> 00:16:22.860
and eventually to also listen for the click event

354
00:16:22.860 --> 00:16:24.340
on the button,

355
00:16:24.340 --> 00:16:26.720
but let's start with the query here.

356
00:16:26.720 --> 00:16:28.540
And so, let's create a method

357
00:16:28.540 --> 00:16:32.973
that we will then call from the controller called getQuery.

358
00:16:35.490 --> 00:16:36.450
And all this will do

359
00:16:36.450 --> 00:16:40.713
is to return this.#parentElement.

360
00:16:42.690 --> 00:16:43.523
And so again,

361
00:16:43.523 --> 00:16:47.300
that's going to be the search.

362
00:16:47.300 --> 00:16:48.270
And then from there,

363
00:16:48.270 --> 00:16:51.713
we want to select this input field.

364
00:16:53.930 --> 00:16:56.220
So this one with this class.

365
00:16:56.220 --> 00:16:59.470
And so let's a select this child element

366
00:16:59.470 --> 00:17:01.533
using a querySelector,

367
00:17:06.410 --> 00:17:09.913
and then simply get the value of that.

368
00:17:11.209 --> 00:17:14.193
Okay, and that's actually it.

369
00:17:15.330 --> 00:17:16.380
And again, of course

370
00:17:16.380 --> 00:17:19.090
we could have written this exact same code

371
00:17:19.090 --> 00:17:20.320
in a controller,

372
00:17:20.320 --> 00:17:22.560
but that wouldn't make any sense,

373
00:17:22.560 --> 00:17:26.040
because this is not concerned about the DOM at all.

374
00:17:26.040 --> 00:17:29.240
So we don't want to have any DOM elements in here.

375
00:17:29.240 --> 00:17:32.550
We don't even want to know what the DOM looks like.

376
00:17:32.550 --> 00:17:34.730
So actually here we have this,

377
00:17:34.730 --> 00:17:36.130
but we don't want this here.

378
00:17:37.790 --> 00:17:40.393
Let's get rid of all this clutter here actually.

379
00:17:41.890 --> 00:17:44.930
And now, I want to

380
00:17:46.800 --> 00:17:51.203
get the searchView here.

381
00:17:53.610 --> 00:17:54.753
And then here,

382
00:17:56.920 --> 00:17:58.570
we can get that query

383
00:17:59.930 --> 00:18:02.600
by saying searchView.getQuery.

384
00:18:06.110 --> 00:18:06.943
And of course,

385
00:18:06.943 --> 00:18:08.500
there might be no query.

386
00:18:08.500 --> 00:18:11.470
And so, let's add another guard clause here.

387
00:18:11.470 --> 00:18:13.073
So if there is no query,

388
00:18:14.360 --> 00:18:17.050
then return immediately.

389
00:18:17.050 --> 00:18:17.883
And so here,

390
00:18:17.883 --> 00:18:21.620
we will now no longer look for pizza,

391
00:18:21.620 --> 00:18:22.663
but for query.

392
00:18:23.690 --> 00:18:24.710
Now, if we run this,

393
00:18:24.710 --> 00:18:27.430
then of course there will be no result

394
00:18:27.430 --> 00:18:30.200
because, well, right now,

395
00:18:30.200 --> 00:18:32.223
there is nothing here to be found.

396
00:18:33.290 --> 00:18:34.780
So that controller function

397
00:18:34.780 --> 00:18:36.610
runs right in the beginning

398
00:18:36.610 --> 00:18:38.830
when the application actually loads.

399
00:18:38.830 --> 00:18:40.270
And so by then of course,

400
00:18:40.270 --> 00:18:43.150
there is a no value here.

401
00:18:43.150 --> 00:18:45.660
And so, in order to actually make this work,

402
00:18:45.660 --> 00:18:48.040
we now need to listen for the event

403
00:18:48.040 --> 00:18:53.040
of basically clicking this button or submitting this form.

404
00:18:53.190 --> 00:18:55.350
And then, only on that event,

405
00:18:55.350 --> 00:18:57.300
we want to actually call,

406
00:18:57.300 --> 00:18:59.200
this controller function here.

407
00:18:59.200 --> 00:19:01.723
So not in the beginning when the script loads.

408
00:19:02.610 --> 00:19:04.600
So, in order to do that,

409
00:19:04.600 --> 00:19:05.930
we will once again,

410
00:19:05.930 --> 00:19:08.950
use the publisher subscriber pattern.

411
00:19:08.950 --> 00:19:13.950
So basically exactly what we did here, right?

412
00:19:14.580 --> 00:19:16.640
So we will list in for the event

413
00:19:16.640 --> 00:19:19.450
in the view right here,

414
00:19:19.450 --> 00:19:21.810
and then pass the controller function.

415
00:19:21.810 --> 00:19:23.260
So the handler function

416
00:19:24.170 --> 00:19:26.593
into the method that we will build here.

417
00:19:28.440 --> 00:19:32.400
So this addHandler, a search method here

418
00:19:32.400 --> 00:19:33.560
is basically going

419
00:19:33.560 --> 00:19:37.770
to be the publisher anti-control search results function

420
00:19:37.770 --> 00:19:39.893
is going to be the subscriber.

421
00:19:41.690 --> 00:19:46.160
Okay, so hopefully you really understood that pattern

422
00:19:46.160 --> 00:19:48.170
that we used before.

423
00:19:48.170 --> 00:19:49.003
And so this now,

424
00:19:49.003 --> 00:19:50.223
it should be obvious.

425
00:19:51.310 --> 00:19:54.160
So, let's take our parent element.

426
00:19:54.160 --> 00:19:57.050
So this.#parentElement of course,

427
00:19:57.050 --> 00:19:58.030
and then this is where

428
00:19:58.030 --> 00:20:00.830
we will actually add the event listener.

429
00:20:00.830 --> 00:20:02.680
So not to the button,

430
00:20:02.680 --> 00:20:04.750
but really to the entire form

431
00:20:04.750 --> 00:20:08.670
because there, we can listen for the submit event.

432
00:20:08.670 --> 00:20:10.460
And so then, this will work

433
00:20:10.460 --> 00:20:13.320
no matter if the user clicks the submit button

434
00:20:13.320 --> 00:20:17.303
or if the user hits Enter while typing the query.

435
00:20:18.640 --> 00:20:22.200
Now here, we cannot simply call the handler immediately,

436
00:20:22.200 --> 00:20:25.810
because remember, as we did many times before

437
00:20:25.810 --> 00:20:27.350
when we submit a form,

438
00:20:27.350 --> 00:20:30.680
we need to first prevent the default action,

439
00:20:30.680 --> 00:20:33.353
because otherwise the page is going to reload.

440
00:20:35.010 --> 00:20:36.897
So, preventDefault.

441
00:20:39.890 --> 00:20:41.830
And only after that,

442
00:20:41.830 --> 00:20:44.770
we can call the handler function.

443
00:20:44.770 --> 00:20:46.770
And, as you already know,

444
00:20:46.770 --> 00:20:48.290
this handler function

445
00:20:48.290 --> 00:20:51.550
should be the control searchResults function.

446
00:20:51.550 --> 00:20:52.940
And so, all we have to do now

447
00:20:52.940 --> 00:20:54.900
is to call this method

448
00:20:54.900 --> 00:20:57.293
and pass in that function.

449
00:20:58.590 --> 00:21:00.890
So, let's do that here right at the beginning.

450
00:21:01.890 --> 00:21:03.123
So searchView.addHandlerSearch.

451
00:21:07.040 --> 00:21:09.660
So you'll see that I'm always going to use

452
00:21:09.660 --> 00:21:11.590
this name here of addHandler,

453
00:21:13.840 --> 00:21:16.740
and then we pass in the controller function

454
00:21:17.740 --> 00:21:19.430
and that's it.

455
00:21:19.430 --> 00:21:21.833
So now it should actually already work.

456
00:21:23.460 --> 00:21:24.780
So let's see.

457
00:21:24.780 --> 00:21:27.680
And actually, let's clear up all this clutter

458
00:21:27.680 --> 00:21:28.623
here a little bit.

459
00:21:29.550 --> 00:21:32.270
Okay, so this console.log,

460
00:21:32.270 --> 00:21:35.413
and there's also some here in the recipe view.

461
00:21:36.380 --> 00:21:37.423
So that's this one.

462
00:21:40.470 --> 00:21:43.400
Okay, so that's again, try pizza

463
00:21:44.470 --> 00:21:48.033
and yeah, beautiful, it worked.

464
00:21:49.240 --> 00:21:50.930
So we get

465
00:21:50.930 --> 00:21:53.890
this data first here coming from the model,

466
00:21:53.890 --> 00:21:55.630
and then also in a controller,

467
00:21:55.630 --> 00:21:57.140
we also logged it.

468
00:21:57.140 --> 00:22:01.290
And so here we have the exact same 59 data

469
00:22:01.290 --> 00:22:02.293
that we had before.

470
00:22:03.130 --> 00:22:05.060
Let's try something else now,

471
00:22:05.060 --> 00:22:06.403
avocado, let's say,

472
00:22:08.020 --> 00:22:09.343
so I hit Enter,

473
00:22:10.910 --> 00:22:15.320
and, so this time we got 39 search results

474
00:22:16.650 --> 00:22:17.483
and you see,

475
00:22:17.483 --> 00:22:20.250
all of them basically have avocado

476
00:22:20.250 --> 00:22:22.400
right there in the title,

477
00:22:22.400 --> 00:22:23.650
it's really beautiful

478
00:22:23.650 --> 00:22:25.833
that it already works this great.

479
00:22:26.670 --> 00:22:28.800
Now just one small detail,

480
00:22:28.800 --> 00:22:30.460
is that, after we search,

481
00:22:30.460 --> 00:22:33.450
we should probably clear out this field.

482
00:22:33.450 --> 00:22:36.873
So let's add another small method for that in the view.

483
00:22:37.960 --> 00:22:40.053
So, and this one here,

484
00:22:42.030 --> 00:22:42.933
so clearInput,

485
00:22:44.900 --> 00:22:46.590
and once again,

486
00:22:46.590 --> 00:22:51.420
having it nicely encapsulated inside of the searchView.

487
00:22:51.420 --> 00:22:54.850
So again, this could simply be also in a controller,

488
00:22:54.850 --> 00:22:57.700
because, it's really just one line of code,

489
00:22:57.700 --> 00:23:00.750
but we want to keep everything separated.

490
00:23:00.750 --> 00:23:03.510
This will make it so much easier to add features

491
00:23:03.510 --> 00:23:05.110
in the future.

492
00:23:05.110 --> 00:23:06.660
And it's really so much better.

493
00:23:08.060 --> 00:23:12.663
So, all we do is to set this to empty and that's it.

494
00:23:14.050 --> 00:23:16.950
All right, let's try it one more time.

495
00:23:16.950 --> 00:23:18.543
Let's say pasta this time.

496
00:23:19.860 --> 00:23:24.860
Ah, of course we never called DOM method here anywhere.

497
00:23:25.090 --> 00:23:27.383
So we need to do that in the controller.

498
00:23:28.760 --> 00:23:31.603
And let's actually add some more comments here.

499
00:23:34.100 --> 00:23:35.943
So Get search query.

500
00:23:38.290 --> 00:23:42.950
And the code itself is actually pretty self explanatory.

501
00:23:42.950 --> 00:23:45.010
And so many developers will tell you

502
00:23:45.010 --> 00:23:46.760
you should not comment it,

503
00:23:46.760 --> 00:23:47.593
but I think

504
00:23:47.593 --> 00:23:50.740
that this is actually very helpful when you read the code

505
00:23:50.740 --> 00:23:53.003
in like one or two years from now.

506
00:23:54.960 --> 00:23:59.960
So, I would advise you to always write comments like this

507
00:24:00.120 --> 00:24:03.110
even if your code seems pretty obvious,

508
00:24:03.110 --> 00:24:04.540
especially when it's like

509
00:24:04.540 --> 00:24:07.103
a bigger list of instructions like this,

510
00:24:08.770 --> 00:24:11.870
so Render results.

511
00:24:11.870 --> 00:24:15.483
So right now our rendering is only a console.log.

512
00:24:16.520 --> 00:24:19.150
But here, when we get a search query,

513
00:24:19.150 --> 00:24:20.580
we can actually then

514
00:24:20.580 --> 00:24:24.030
immediately also clear it afterwards.

515
00:24:24.030 --> 00:24:25.880
Or in fact,

516
00:24:25.880 --> 00:24:28.860
in order to keep this controller even simpler,

517
00:24:28.860 --> 00:24:29.780
we can do that

518
00:24:29.780 --> 00:24:32.340
right in the getQuery method.

519
00:24:32.340 --> 00:24:35.690
So, let's go back here,

520
00:24:35.690 --> 00:24:37.720
and now we can make this private,

521
00:24:37.720 --> 00:24:40.223
so we're not going to use it outside.

522
00:24:41.170 --> 00:24:43.640
And then let's actually call it here.

523
00:24:43.640 --> 00:24:45.383
So this.#clearInput.

524
00:24:51.601 --> 00:24:52.434
And then of course,

525
00:24:52.434 --> 00:24:55.923
we first need to store this somewhere here.

526
00:25:00.500 --> 00:25:01.980
So we get the query,

527
00:25:01.980 --> 00:25:03.340
then we clear the field

528
00:25:04.220 --> 00:25:06.173
and then we return the query.

529
00:25:08.150 --> 00:25:10.963
All right, so that should now work.

530
00:25:13.674 --> 00:25:16.280
So pasta and clears the field,

531
00:25:16.280 --> 00:25:21.053
and gives us or 45 results down here about pasta.

532
00:25:22.050 --> 00:25:25.810
Great, so that works just fine.

533
00:25:25.810 --> 00:25:27.500
And so, all there's left to do

534
00:25:27.500 --> 00:25:31.110
is to now implement actually the view.

535
00:25:31.110 --> 00:25:33.290
So the second view basically.

536
00:25:33.290 --> 00:25:34.670
So the one

537
00:25:34.670 --> 00:25:35.690
that is responsible

538
00:25:35.690 --> 00:25:37.960
for then rendering all the results

539
00:25:37.960 --> 00:25:39.800
here in this sidebar.

540
00:25:39.800 --> 00:25:42.400
And so that's going to be a little bit of work.

541
00:25:42.400 --> 00:25:44.633
So let's leave that for the next video.

