WEBVTT

1
00:00:01.340 --> 00:00:04.840
<v ->So let's now learn how we can listen for events</v>

2
00:00:04.840 --> 00:00:09.140
and also handle events in our MVC architecture

3
00:00:09.140 --> 00:00:13.083
by using something called the Publisher-Subscriber pattern.

4
00:00:15.130 --> 00:00:17.480
And let's start by analyzing the code

5
00:00:17.480 --> 00:00:18.993
that we already have here.

6
00:00:20.060 --> 00:00:22.800
So right now we are listening for the hashchange

7
00:00:24.070 --> 00:00:28.270
and for the load events right here in the controller.

8
00:00:28.270 --> 00:00:32.150
However, that doesn't make a lot of sense, does it?

9
00:00:32.150 --> 00:00:35.610
Because everything that is related to the DOM,

10
00:00:35.610 --> 00:00:40.270
so to the view, should really be inside of a view.

11
00:00:40.270 --> 00:00:43.840
Now, maybe these two events here don't really look

12
00:00:43.840 --> 00:00:47.090
as if they have to do with the view,

13
00:00:47.090 --> 00:00:49.150
so with the user interface.

14
00:00:49.150 --> 00:00:52.700
But imagine that instead we would be handling a click event

15
00:00:52.700 --> 00:00:55.150
on some DOM element.

16
00:00:55.150 --> 00:00:58.840
And so listening for that event should for sure,

17
00:00:58.840 --> 00:01:00.650
go into the view.

18
00:01:00.650 --> 00:01:04.830
And therefore, we can say the same about these events here.

19
00:01:04.830 --> 00:01:08.720
So in the end, this has more to do with DOM manipulation

20
00:01:08.720 --> 00:01:12.790
or what to DOM itself then actually with the controller.

21
00:01:12.790 --> 00:01:16.700
And so therefore, we need a way of putting this logic here

22
00:01:16.700 --> 00:01:19.880
into a recipe view.

23
00:01:19.880 --> 00:01:23.100
However, the handler function that we use

24
00:01:23.100 --> 00:01:26.363
to handle these events is actually this controller.

25
00:01:27.636 --> 00:01:29.590
So it's this function that we have up here

26
00:01:29.590 --> 00:01:33.060
that is sitting inside of this controller module.

27
00:01:33.060 --> 00:01:37.130
And so we have basically a problem here.

28
00:01:37.130 --> 00:01:39.890
We don't want this code to be here

29
00:01:39.890 --> 00:01:42.360
so we want it to be in the view.

30
00:01:42.360 --> 00:01:45.810
But in this code, we need this controller function

31
00:01:45.810 --> 00:01:47.930
which is here in this module.

32
00:01:47.930 --> 00:01:49.440
And of course, we don't want

33
00:01:49.440 --> 00:01:51.910
to put this function in the view.

34
00:01:51.910 --> 00:01:53.550
And so let's now think about

35
00:01:53.550 --> 00:01:55.323
how we could solve this problem.

36
00:01:57.330 --> 00:02:00.700
And recapping everything that I just said before,

37
00:02:00.700 --> 00:02:03.810
we can basically say that we want to handle events

38
00:02:03.810 --> 00:02:06.630
in the controller because otherwise,

39
00:02:06.630 --> 00:02:09.840
we would have application logic in the view,

40
00:02:09.840 --> 00:02:12.170
and of course we don't want that.

41
00:02:12.170 --> 00:02:13.550
But on the other hand,

42
00:02:13.550 --> 00:02:16.460
we want to listen for events in the view,

43
00:02:16.460 --> 00:02:19.500
because otherwise we would need DOM elements

44
00:02:19.500 --> 00:02:20.940
in the controller,

45
00:02:20.940 --> 00:02:23.820
and we would basically have presentation logic

46
00:02:23.820 --> 00:02:26.500
in the a controller which would be wrong

47
00:02:26.500 --> 00:02:29.120
in our MVC implementation.

48
00:02:29.120 --> 00:02:32.630
So essentially, event listeners should be attached

49
00:02:32.630 --> 00:02:34.810
to DOM elements in the view,

50
00:02:34.810 --> 00:02:37.170
but the events should then be handled

51
00:02:37.170 --> 00:02:41.700
by controller functions that live in the controller module.

52
00:02:41.700 --> 00:02:45.440
And so if you take a look at this small diagram

53
00:02:45.440 --> 00:02:48.720
that is just a part of the architecture diagram

54
00:02:48.720 --> 00:02:50.313
that we already saw before,

55
00:02:51.748 --> 00:02:53.230
so here we have to controlRecipes function

56
00:02:53.230 --> 00:02:54.520
in the controller,

57
00:02:54.520 --> 00:02:57.470
and we have a special method in the view,

58
00:02:57.470 --> 00:03:00.460
which is called addHandlerRender.

59
00:03:00.460 --> 00:03:04.360
Now, we might think that it is very easy to connect

60
00:03:04.360 --> 00:03:06.290
these two functions

61
00:03:06.290 --> 00:03:10.730
because why not simply call the control recipe's function

62
00:03:10.730 --> 00:03:14.670
right from the view whenever an event occurs?

63
00:03:14.670 --> 00:03:17.330
Well, that's actually not possible

64
00:03:17.330 --> 00:03:20.240
because in a way we set up the architecture,

65
00:03:20.240 --> 00:03:24.200
the view does not know anything about the controller.

66
00:03:24.200 --> 00:03:26.760
So it doesn't import the controller,

67
00:03:26.760 --> 00:03:29.230
and so we can't call any of the functions

68
00:03:29.230 --> 00:03:32.090
that are in the controller from the view.

69
00:03:32.090 --> 00:03:34.310
So it only works the other way around

70
00:03:34.310 --> 00:03:37.970
and therefore it's more complex than this.

71
00:03:37.970 --> 00:03:42.270
But fortunately, there is a good solution and this solution

72
00:03:42.270 --> 00:03:46.420
is called the Publisher-Subscriber Design pattern.

73
00:03:46.420 --> 00:03:50.080
And by the way, design patterns in programming

74
00:03:50.080 --> 00:03:52.650
are basically just standard solutions

75
00:03:52.650 --> 00:03:55.440
to certain kinds of problems.

76
00:03:55.440 --> 00:04:00.190
So in the publisher-Subscriber pattern we have a publisher

77
00:04:00.190 --> 00:04:04.470
which is some code that knows when to react.

78
00:04:04.470 --> 00:04:05.530
And in this case,

79
00:04:05.530 --> 00:04:08.530
that's going to be the addHandlerRender function

80
00:04:08.530 --> 00:04:12.390
because it will contain the addEventListener method.

81
00:04:12.390 --> 00:04:17.020
And therefore, it will know when to react to the event.

82
00:04:17.020 --> 00:04:20.460
Now, on the other hand, we have a subscriber

83
00:04:20.460 --> 00:04:24.320
which is code that actually wants to react.

84
00:04:24.320 --> 00:04:27.750
So this is the code that should actually be executed

85
00:04:27.750 --> 00:04:29.950
when the event happens.

86
00:04:29.950 --> 00:04:33.490
And in this case, that is the controlRecipes function

87
00:04:33.490 --> 00:04:36.510
that we already have in our controller.

88
00:04:36.510 --> 00:04:40.520
And remember that the publisher does not know yet

89
00:04:40.520 --> 00:04:42.930
that the subscriber even exists

90
00:04:42.930 --> 00:04:46.070
because that subscriber is in the controller

91
00:04:46.070 --> 00:04:48.690
that the view cannot access.

92
00:04:48.690 --> 00:04:49.523
Okay.

93
00:04:49.523 --> 00:04:53.700
But now finally comes to solution to the problem.

94
00:04:53.700 --> 00:04:57.080
So the solution is that we can now subscribe

95
00:04:57.080 --> 00:05:01.010
to the publisher by passing into subscriber function

96
00:05:01.010 --> 00:05:03.070
as an argument.

97
00:05:03.070 --> 00:05:05.290
Now in practice, that means that

98
00:05:05.290 --> 00:05:09.870
as soon as the program loads, the init function is called

99
00:05:09.870 --> 00:05:11.820
which in turn immediately calls

100
00:05:11.820 --> 00:05:15.430
the addHandlerRender function from the view.

101
00:05:15.430 --> 00:05:19.340
And that is possible, remember, because the controller

102
00:05:20.211 --> 00:05:23.653
does in fact import both the view and the model, right?

103
00:05:24.650 --> 00:05:28.120
Now, anyway, as we call addHendlerRender,

104
00:05:28.120 --> 00:05:33.120
we pass in our controlRecipes function as an argument.

105
00:05:33.300 --> 00:05:37.330
So essentially, we subscribe controlRecipes

106
00:05:37.330 --> 00:05:39.460
to addHandlerRender.

107
00:05:39.460 --> 00:05:42.170
And so at this point, the two functions

108
00:05:42.170 --> 00:05:45.330
are basically finally connected.

109
00:05:45.330 --> 00:05:49.580
And so now addHandlerRender listens for events

110
00:05:49.580 --> 00:05:53.456
using the addEventListener method as always.

111
00:05:53.456 --> 00:05:57.323
And then as soon as the event actually happens,

112
00:05:57.323 --> 00:05:59.570
the controlRecipes function will be called

113
00:05:59.570 --> 00:06:03.550
as the callback function of addEventListener.

114
00:06:03.550 --> 00:06:05.260
Or, in other words,

115
00:06:05.260 --> 00:06:08.650
as soon as the publisher publishes an event

116
00:06:08.650 --> 00:06:10.933
the subscriber will get called.

117
00:06:11.790 --> 00:06:12.660
All right.

118
00:06:12.660 --> 00:06:15.770
And this is how we implement event listeners

119
00:06:15.770 --> 00:06:19.860
and event handlers in the MVC architecture.

120
00:06:19.860 --> 00:06:23.530
So this will allow us to keep the handler in the controller

121
00:06:23.530 --> 00:06:25.620
and to listener in the view.

122
00:06:25.620 --> 00:06:30.030
And by that, keeping everything nicely separated.

123
00:06:30.030 --> 00:06:34.060
So in summary, the handler subscribes to the publisher,

124
00:06:34.060 --> 00:06:36.300
which is the listener in this case,

125
00:06:36.300 --> 00:06:39.830
and then as the publisher publishes an event,

126
00:06:39.830 --> 00:06:42.093
the subscriber is executed.

127
00:06:42.930 --> 00:06:45.790
And if you want to think even deeper about this

128
00:06:45.790 --> 00:06:47.890
and are really interested in this,

129
00:06:47.890 --> 00:06:51.780
then notice how there is actually a profound difference

130
00:06:51.780 --> 00:06:55.550
between a certain arbitrary like function A

131
00:06:55.550 --> 00:06:58.600
simply calling function B directly

132
00:06:58.600 --> 00:07:02.840
and function A receiving function B as an input

133
00:07:02.840 --> 00:07:06.160
in order to then call that input function.

134
00:07:06.160 --> 00:07:08.920
So this is all about control.

135
00:07:08.920 --> 00:07:12.780
In the first scenario, function A is in control.

136
00:07:12.780 --> 00:07:17.440
However, in the second scenario function A has no control.

137
00:07:17.440 --> 00:07:22.330
So it simply has to execute whatever function it receives.

138
00:07:22.330 --> 00:07:25.490
So if you want, reflect a little bit on that

139
00:07:25.490 --> 00:07:27.710
and see that this is exactly

140
00:07:27.710 --> 00:07:32.490
what the Publisher-Subscriber pattern is actually all about.

141
00:07:32.490 --> 00:07:36.310
But anyway, leaving that theory aside now,

142
00:07:36.310 --> 00:07:39.913
let's go back to our code and implement all of this.

143
00:07:41.490 --> 00:07:43.690
And so with everything we just learned

144
00:07:43.690 --> 00:07:46.690
about the Publisher-Subscriber pattern,

145
00:07:46.690 --> 00:07:48.550
actually, now implementing it

146
00:07:48.550 --> 00:07:51.423
should be the easiest part, right?

147
00:07:52.540 --> 00:07:55.153
So let's simply grab this code.

148
00:07:56.260 --> 00:07:57.750
So cutting it actually

149
00:07:58.940 --> 00:08:02.370
and then here we will create a new method

150
00:08:03.430 --> 00:08:07.440
and let's just put it somewhere, let's say here.

151
00:08:07.440 --> 00:08:09.983
And so this will be our addHandlerRender method

152
00:08:13.890 --> 00:08:15.333
that we just talked about.

153
00:08:17.070 --> 00:08:21.480
So addHandlerRender because this is going to be

154
00:08:21.480 --> 00:08:26.250
for rendering the recipe right at the beginning, right?

155
00:08:26.250 --> 00:08:30.490
And then this method, which remember, is the publisher

156
00:08:30.490 --> 00:08:34.000
basically needs to get access to the subscriber.

157
00:08:34.000 --> 00:08:36.673
And so that in this case is the handler function.

158
00:08:40.230 --> 00:08:41.063
All right?

159
00:08:42.363 --> 00:08:45.530
And so then we can simply paste that in here.

160
00:08:45.530 --> 00:08:49.470
And then here, of course we don't know about controlRecipes,

161
00:08:49.470 --> 00:08:51.103
but we know about the handler.

162
00:08:52.950 --> 00:08:56.630
And so that's actually it for this function.

163
00:08:56.630 --> 00:08:59.370
So of course it is not a private method

164
00:08:59.370 --> 00:09:03.990
because it needs to be part of the public API of this object

165
00:09:03.990 --> 00:09:07.780
so that we can then call it in the controller, right.

166
00:09:07.780 --> 00:09:10.343
And so let's actually do that now.

167
00:09:11.520 --> 00:09:13.670
So we can get rid of this now.

168
00:09:13.670 --> 00:09:16.480
And we will want to do this right in the beginning.

169
00:09:16.480 --> 00:09:18.573
So let's create an init function here,

170
00:09:20.520 --> 00:09:22.283
actually like this,

171
00:09:25.843 --> 00:09:28.270
and then we simply call it right at the beginning.

172
00:09:28.270 --> 00:09:29.990
So only once.

173
00:09:29.990 --> 00:09:32.560
And actually we could simply put all the code

174
00:09:32.560 --> 00:09:34.710
also here in the global scope,

175
00:09:34.710 --> 00:09:36.560
but I think it's a bit cleaner

176
00:09:36.560 --> 00:09:38.913
to have a separate function for this.

177
00:09:39.770 --> 00:09:44.723
That's recipeView.addHandlerRender.

178
00:09:45.780 --> 00:09:49.783
And so now we simply pass in controlRecipes,

179
00:09:51.481 --> 00:09:53.424
and that's actually it.

180
00:09:53.424 --> 00:09:54.460
With this, we just implemented

181
00:09:54.460 --> 00:09:57.220
the Publisher-Subscriber pattern.

182
00:09:57.220 --> 00:10:00.700
For some reason, we're still getting these errors here.

183
00:10:00.700 --> 00:10:03.140
Let's get rid of this alert here actually,

184
00:10:03.140 --> 00:10:05.283
and simply do a console.log here.

185
00:10:08.900 --> 00:10:09.810
Okay.

186
00:10:09.810 --> 00:10:13.033
But now let's go and see if this actually works.

187
00:10:15.690 --> 00:10:17.653
We're still having our slow network.

188
00:10:22.910 --> 00:10:26.430
Oh, and here we have some problem apparently

189
00:10:26.430 --> 00:10:28.220
with the timeout.

190
00:10:28.220 --> 00:10:31.933
So let's go quickly fix that here in the helpers.

191
00:10:32.940 --> 00:10:37.590
So we saw that here it said undefined,

192
00:10:37.590 --> 00:10:39.930
like after undefined second.

193
00:10:39.930 --> 00:10:43.200
So maybe this variable here doesn't exist.

194
00:10:43.200 --> 00:10:46.600
So maybe it's misspelled.

195
00:10:46.600 --> 00:10:47.950
So let's see in the config.

196
00:10:50.206 --> 00:10:51.256
Well, it looks right.

197
00:10:55.570 --> 00:10:57.053
Yeah, it is the same.

198
00:10:58.710 --> 00:11:00.433
Well, let's see again.

199
00:11:01.980 --> 00:11:05.190
And so this apparently happens immediately

200
00:11:05.190 --> 00:11:06.240
for some reason here.

201
00:11:10.300 --> 00:11:14.053
So what if we put it back to some normal number?

202
00:11:15.210 --> 00:11:18.990
Well, then it works, which is very weird

203
00:11:20.160 --> 00:11:22.983
because this is in fact also 10.

204
00:11:25.830 --> 00:11:29.773
So let's see what we get here as we lock timeout seconds.

205
00:11:32.010 --> 00:11:35.640
Oh, I'm actually right now seeing the problem.

206
00:11:35.640 --> 00:11:38.860
So this is not helpers, it is config.

207
00:11:38.860 --> 00:11:40.773
So we are importing ourselves here.

208
00:11:42.400 --> 00:11:44.023
So that was the problem.

209
00:11:47.390 --> 00:11:48.863
Let's put everything back.

210
00:11:50.110 --> 00:11:52.423
And you see that now it is working.

211
00:11:53.570 --> 00:11:55.913
Even with the hashchange event.

212
00:11:57.790 --> 00:12:01.690
And so that means that we did now successfully implement

213
00:12:01.690 --> 00:12:04.800
the Publisher-Subscriber pattern.

214
00:12:04.800 --> 00:12:05.710
Okay?

215
00:12:05.710 --> 00:12:10.263
And so let's quickly recap what exactly is happening here.

216
00:12:11.970 --> 00:12:15.523
So we can also take a look at our final diagram here.

217
00:12:16.690 --> 00:12:20.760
And here, I actually have the event here in the controller

218
00:12:20.760 --> 00:12:23.940
because that is actually where it is handled.

219
00:12:23.940 --> 00:12:26.220
And so I think that in this diagram,

220
00:12:26.220 --> 00:12:28.150
this makes it a little bit easier

221
00:12:28.150 --> 00:12:31.540
to actually understand the flow of the program.

222
00:12:31.540 --> 00:12:35.720
So anyway, as we start to program

223
00:12:35.720 --> 00:12:38.490
then the init function runs

224
00:12:38.490 --> 00:12:43.170
and it will then immediately run addHandlerRender, right?

225
00:12:43.170 --> 00:12:45.760
So it is this function here.

226
00:12:45.760 --> 00:12:47.750
And it's this function that is actually

227
00:12:47.750 --> 00:12:50.950
listening for events right here in the view

228
00:12:50.950 --> 00:12:53.130
where it actually makes sense.

229
00:12:53.130 --> 00:12:57.480
Now, as we call this method here, so in the controller,

230
00:12:57.480 --> 00:13:01.610
we pass in the controller function or the handler function

231
00:13:01.610 --> 00:13:05.950
that we want to get executed as soon as the event happens,

232
00:13:05.950 --> 00:13:06.783
right?

233
00:13:06.783 --> 00:13:09.430
And here we then receive that function

234
00:13:09.430 --> 00:13:11.430
as being called handler.

235
00:13:11.430 --> 00:13:13.540
And so that's what we then call

236
00:13:13.540 --> 00:13:16.940
as soon as the event happens, right?

237
00:13:16.940 --> 00:13:18.620
And so again in our diagram,

238
00:13:18.620 --> 00:13:20.563
that's exactly what we have here.

239
00:13:21.910 --> 00:13:24.440
So that's why I have this dotted line here

240
00:13:24.440 --> 00:13:26.310
which stands for data flow.

241
00:13:26.310 --> 00:13:29.490
So we are passing in the controlRecipe function

242
00:13:29.490 --> 00:13:31.780
as the handler here.

243
00:13:31.780 --> 00:13:33.320
And that is the whole reason

244
00:13:33.320 --> 00:13:37.520
why the method here is called addHandlerRender.

245
00:13:37.520 --> 00:13:40.430
So because we are using it to, in fact,

246
00:13:40.430 --> 00:13:43.140
add a handler function and in this case,

247
00:13:43.140 --> 00:13:46.530
it is for rendering the recipe in the first place.

248
00:13:46.530 --> 00:13:47.630
And then later on,

249
00:13:47.630 --> 00:13:51.263
we will actually have other addHandler methods.

250
00:13:52.200 --> 00:13:53.033
Okay?

251
00:13:53.033 --> 00:13:57.030
And so it's crucial that you understand this logic here

252
00:13:57.030 --> 00:14:01.000
before you can move on any further in this project.

253
00:14:01.000 --> 00:14:03.670
But I hope that with all this explanation,

254
00:14:03.670 --> 00:14:05.530
this became all really clear

255
00:14:05.530 --> 00:14:09.200
and also obvious why we had to do it like this.

256
00:14:09.200 --> 00:14:12.440
I mean, of course we don't really have to do it,

257
00:14:12.440 --> 00:14:15.470
so we are, of course, in charge of our own code.

258
00:14:15.470 --> 00:14:19.690
But in order to correctly implement the MVC architecture,

259
00:14:19.690 --> 00:14:22.110
this is the best way of doing it.

260
00:14:22.110 --> 00:14:26.330
And so again, then we can keep everything nicely separated

261
00:14:26.330 --> 00:14:30.070
into a model controller and view

262
00:14:30.070 --> 00:14:33.880
without any overlapping responsibilities.

263
00:14:33.880 --> 00:14:34.960
All right.

264
00:14:34.960 --> 00:14:39.160
So we have all of this structure here now nicely set up,

265
00:14:39.160 --> 00:14:41.280
everything is nicely separated.

266
00:14:41.280 --> 00:14:43.920
And so from now on, all we have to do

267
00:14:43.920 --> 00:14:47.150
is to basically use this structure to implement

268
00:14:47.150 --> 00:14:50.390
all of the missing features off our application.

269
00:14:50.390 --> 00:14:53.850
And so again, really make sure that you understand

270
00:14:53.850 --> 00:14:56.070
everything that we did so far,

271
00:14:56.070 --> 00:15:00.560
especially regarding the implementation of our architecture.

272
00:15:00.560 --> 00:15:04.000
And then once you are really done with understanding that,

273
00:15:04.000 --> 00:15:06.373
let's go straight to the next video.

