1
00:00:02,000 --> 00:00:03,000
So let's work on the front end again

2
00:00:03,000 --> 00:00:05,000
and let's give the users some feedback

3
00:00:05,000 --> 00:00:07,000
about what's going on.

4
00:00:07,000 --> 00:00:09,000
For this I'll use a similar approach

5
00:00:09,000 --> 00:00:11,000
as I did earlier in the course.

6
00:00:11,000 --> 00:00:13,000
I'll show some notifications.

7
00:00:13,000 --> 00:00:14,000
For a dis-a-tach,

8
00:00:14,000 --> 00:00:17,000
you find a UI zipped file, which you can extract

9
00:00:17,000 --> 00:00:21,000
and then just move into your components folder.

10
00:00:21,000 --> 00:00:23,000
It's a folder, a UI folder.

11
00:00:23,000 --> 00:00:25,000
Then with one component in it,

12
00:00:25,000 --> 00:00:28,000
the notification component, with some styles.

13
00:00:28,000 --> 00:00:31,000
And if you followed along with the previous core sections

14
00:00:31,000 --> 00:00:33,000
this will look fairly familiar.

15
00:00:33,000 --> 00:00:35,000
That's a notification which we can show

16
00:00:35,000 --> 00:00:37,000
at the bottom of the screen to give to users

17
00:00:37,000 --> 00:00:41,000
some indication for Weber Data is on its way,

18
00:00:41,000 --> 00:00:44,000
it's exceeded, or if the request failed.

19
00:00:44,000 --> 00:00:47,000
And I wanna utilize this again now.

20
00:00:47,000 --> 00:00:49,000
Now before in this course,

21
00:00:49,000 --> 00:00:53,000
we implemented this with context, with the context API.

22
00:00:53,000 --> 00:00:57,000
I used context there because we triggered this notification

23
00:00:57,000 --> 00:01:01,000
from different places in our application.

24
00:01:01,000 --> 00:01:03,000
Here in this blog project,

25
00:01:03,000 --> 00:01:06,000
we actually don't have that scenario.

26
00:01:06,000 --> 00:01:09,000
Here, we actually only need to do a notification

27
00:01:09,000 --> 00:01:12,000
for the contact form.

28
00:01:12,000 --> 00:01:14,000
We could still use context though

29
00:01:14,000 --> 00:01:16,000
to make this more versatile

30
00:01:16,000 --> 00:01:19,000
and allow using it in different parts.

31
00:01:19,000 --> 00:01:22,000
But we could also just use notification,

32
00:01:22,000 --> 00:01:25,000
this component in the contact form component only.

33
00:01:25,000 --> 00:01:29,000
And not set up context and all the other parts to manage it.

34
00:01:29,000 --> 00:01:30,000
And I will do that.

35
00:01:30,000 --> 00:01:33,000
I will just use it locally here,

36
00:01:33,000 --> 00:01:35,000
but of course as an extra exercise,

37
00:01:35,000 --> 00:01:38,000
definitely also feel free to use context again,

38
00:01:38,000 --> 00:01:42,000
just as we did it earlier in the course.

39
00:01:42,000 --> 00:01:44,000
Now as I said I'll use it locally though

40
00:01:44,000 --> 00:01:46,000
And therefore in the contact form component,

41
00:01:46,000 --> 00:01:49,000
I'll import notification from

42
00:01:50,000 --> 00:01:53,000
going up one level UI notification.

43
00:01:54,000 --> 00:01:58,000
And the goal is to show it whilst the request is on its way

44
00:01:58,000 --> 00:01:59,000
and also once it's done.

45
00:01:59,000 --> 00:02:02,000
Once we have a success or an error.

46
00:02:02,000 --> 00:02:05,000
That means that we need a new piece of state here.

47
00:02:05,000 --> 00:02:08,000
We need to find out what our current state is.

48
00:02:08,000 --> 00:02:13,000
So add use state and don't set any initial value

49
00:02:13,000 --> 00:02:14,000
but I'll name it,

50
00:02:15,000 --> 00:02:20,000
request status and set request status.

51
00:02:20,000 --> 00:02:23,000
And request status can be pending, success or error.

52
00:02:23,000 --> 00:02:25,000
That's my definition.

53
00:02:25,000 --> 00:02:30,000
So pending, success or error.

54
00:02:30,000 --> 00:02:33,000
That are the three possible values we can save in there

55
00:02:33,000 --> 00:02:36,000
or no undefined initially

56
00:02:36,000 --> 00:02:40,000
if we have no ongoing or finished request.

57
00:02:42,000 --> 00:02:44,000
Okay. So now we wanna set the request status,

58
00:02:44,000 --> 00:02:47,000
as we send our request here.

59
00:02:47,000 --> 00:02:50,000
Now I used fetch with then

60
00:02:50,000 --> 00:02:53,000
and catch in the previous core sections,

61
00:02:53,000 --> 00:02:55,000
and we could do this here as well,

62
00:02:55,000 --> 00:02:58,000
but to mix things up and because it's a bit more convenient

63
00:02:58,000 --> 00:03:01,000
to work with fetch when using async/await,

64
00:03:01,000 --> 00:03:03,000
I will use async/await here.

65
00:03:03,000 --> 00:03:06,000
And I'll turn the sent message handler function

66
00:03:06,000 --> 00:03:08,000
into an async function

67
00:03:08,000 --> 00:03:11,000
which allows me to use the await keyword here.

68
00:03:11,000 --> 00:03:13,000
Then we get the response here

69
00:03:13,000 --> 00:03:16,000
and we can use the response thereafter.

70
00:03:17,000 --> 00:03:19,000
Now from the response we want to get the data

71
00:03:19,000 --> 00:03:22,000
by awaiting response, JSON, and now

72
00:03:22,000 --> 00:03:26,000
that's the part where async/await is more convenient.

73
00:03:26,000 --> 00:03:31,000
We can check if response okay is not true.

74
00:03:32,000 --> 00:03:36,000
So if not response okay, which means we have an error.

75
00:03:36,000 --> 00:03:39,000
In this case I will throw a new error

76
00:03:39,000 --> 00:03:42,000
where I set my message equal to data message,

77
00:03:42,000 --> 00:03:44,000
if our response data has a message

78
00:03:44,000 --> 00:03:48,000
or two something went wrong as a fallback.

79
00:03:50,000 --> 00:03:53,000
Else, thereafter we know that everything worked.

80
00:03:53,000 --> 00:03:56,000
Now to not have all this age to DP logic in here,

81
00:03:56,000 --> 00:03:59,000
and to be able to conveniently

82
00:03:59,000 --> 00:04:03,000
try catch the entire HTTP block in one go,

83
00:04:03,000 --> 00:04:05,000
I will grab that code here,

84
00:04:05,000 --> 00:04:08,000
where we fetch and parse the data

85
00:04:08,000 --> 00:04:10,000
and handle the not okay case

86
00:04:10,000 --> 00:04:14,000
and cut debt and move it into a separate function.

87
00:04:14,000 --> 00:04:15,000
A function which we can add

88
00:04:15,000 --> 00:04:18,000
in that same contact form JS file

89
00:04:18,000 --> 00:04:21,000
or a function which we could add in a different file.

90
00:04:21,000 --> 00:04:24,000
Here I'll add it in the same file

91
00:04:24,000 --> 00:04:29,000
and add my async send contact data function.

92
00:04:32,000 --> 00:04:35,000
So async function sent contact data.

93
00:04:36,000 --> 00:04:41,000
And here I now just expect that I get the contact details

94
00:04:43,000 --> 00:04:46,000
as argument and data send the object

95
00:04:46,000 --> 00:04:49,000
which will be added as a body

96
00:04:49,000 --> 00:04:52,000
converted to JSON of course the contact details.

97
00:04:53,000 --> 00:04:55,000
So now I have to logic in here

98
00:04:55,000 --> 00:04:57,000
and now in sent message handler,

99
00:04:57,000 --> 00:05:00,000
we just need to await, send contact data

100
00:05:00,000 --> 00:05:03,000
and pass our object where we set the email to

101
00:05:03,000 --> 00:05:08,000
entered email ends on to that function here.

102
00:05:08,000 --> 00:05:10,000
So here name is set to entered name

103
00:05:10,000 --> 00:05:14,000
and message is set to entered message like this.

104
00:05:14,000 --> 00:05:17,000
Now we still await this, because that's a async function

105
00:05:17,000 --> 00:05:19,000
and we also use await in here.

106
00:05:20,000 --> 00:05:22,000
We could return the data here,

107
00:05:22,000 --> 00:05:23,000
the parse response stayed up,

108
00:05:23,000 --> 00:05:26,000
but since I don't care about it here in this component,

109
00:05:26,000 --> 00:05:28,000
we don't really need to.

110
00:05:29,000 --> 00:05:30,000
So now we got that.

111
00:05:30,000 --> 00:05:32,000
Now that's a bit leaner.

112
00:05:32,000 --> 00:05:36,000
And now, before we send the contact data,

113
00:05:36,000 --> 00:05:38,000
I wanna set my request status.

114
00:05:38,000 --> 00:05:42,000
So update this state here, Q pending.

115
00:05:42,000 --> 00:05:45,000
So I'll set it to pending.

116
00:05:45,000 --> 00:05:47,000
Now once we're done,

117
00:05:47,000 --> 00:05:51,000
thereafter, I wanna send it, set it to success.

118
00:05:53,000 --> 00:05:55,000
If that fails, I wanna set it to error

119
00:05:55,000 --> 00:05:58,000
and hence I'll try this,

120
00:06:00,000 --> 00:06:04,000
here and catch any errors that might be frowned

121
00:06:04,000 --> 00:06:06,000
from anywhere in this request

122
00:06:06,000 --> 00:06:10,000
and set the request status to error.

123
00:06:10,000 --> 00:06:13,000
And hence success is not set thereafter

124
00:06:13,000 --> 00:06:16,000
because dented would also be set if we had an error,

125
00:06:16,000 --> 00:06:17,000
but here inside of try.

126
00:06:18,000 --> 00:06:22,000
Now we have these different status updates

127
00:06:22,000 --> 00:06:25,000
and now we can use them to show our notification.

128
00:06:27,000 --> 00:06:30,000
Now to show the notification,

129
00:06:30,000 --> 00:06:32,000
I wanna render this notification component

130
00:06:32,000 --> 00:06:37,000
which we are already importing based on the status

131
00:06:37,000 --> 00:06:40,000
and based on the status also with different data.

132
00:06:41,000 --> 00:06:45,000
For this in this contact form component function,

133
00:06:45,000 --> 00:06:49,000
I wanna derive the data for my notification.

134
00:06:50,000 --> 00:06:52,000
I'll add a notification data variable

135
00:06:52,000 --> 00:06:54,000
and initially it's undefined.

136
00:06:56,000 --> 00:06:58,000
We can also just name it notification.

137
00:06:58,000 --> 00:07:03,000
But then I'll check if request status is equal to pending

138
00:07:03,000 --> 00:07:04,000
and if that's the case,

139
00:07:04,000 --> 00:07:07,000
I'll set notification equal to an object,

140
00:07:07,000 --> 00:07:10,000
where the status is set to pending,

141
00:07:10,000 --> 00:07:15,000
the title is set to sending message,

142
00:07:15,000 --> 00:07:19,000
and the message of this notification could be set to

143
00:07:22,000 --> 00:07:25,000
your message is on its way.

144
00:07:28,000 --> 00:07:31,000
Now, if request status is equal to success

145
00:07:31,000 --> 00:07:35,000
I wanna set notification to a different object.

146
00:07:35,000 --> 00:07:39,000
Then notification should be set to an object.

147
00:07:39,000 --> 00:07:43,000
Where the status of course is success

148
00:07:43,000 --> 00:07:47,000
where to title is success like this

149
00:07:47,000 --> 00:07:49,000
and where the message is,

150
00:07:49,000 --> 00:07:52,000
message sent successfully.

151
00:07:54,000 --> 00:07:55,000
And last but not least,

152
00:07:55,000 --> 00:07:59,000
the last data package I wanna infer is

153
00:07:59,000 --> 00:08:03,000
for requests status equal to error.

154
00:08:03,000 --> 00:08:07,000
In that case, I wanna set my notification equal to

155
00:08:09,000 --> 00:08:14,000
a status where I set error, a title of error

156
00:08:15,000 --> 00:08:18,000
and now to get the error meagerness

157
00:08:19,000 --> 00:08:23,000
we actually need to get it out of this error object

158
00:08:23,000 --> 00:08:25,000
and set a separate state for that.

159
00:08:28,000 --> 00:08:31,000
So add a new state here, use state request,

160
00:08:35,000 --> 00:08:40,000
error, state and a set request, error updating function.

161
00:08:40,000 --> 00:08:41,000
Initially it's undefined.

162
00:08:41,000 --> 00:08:44,000
But if we have a request error here,

163
00:08:44,000 --> 00:08:49,000
I'll set my request error to

164
00:08:50,000 --> 00:08:52,000
the error message I get here.

165
00:08:52,000 --> 00:08:56,000
So then here, when we derive the data for the notification,

166
00:08:56,000 --> 00:09:00,000
we can set message equal to request error like this.

167
00:09:01,000 --> 00:09:04,000
Okay so now we got the data for the notification

168
00:09:04,000 --> 00:09:06,000
and we could break this component

169
00:09:06,000 --> 00:09:09,000
into multiple smaller components if we wanted to

170
00:09:09,000 --> 00:09:10,000
since it's getting a bit bigger

171
00:09:10,000 --> 00:09:14,000
but I'll leave it as one component for the moment.

172
00:09:14,000 --> 00:09:16,000
Now we have that different data.

173
00:09:16,000 --> 00:09:18,000
We have the different pieces of data.

174
00:09:18,000 --> 00:09:20,000
Now we wanna render the notification

175
00:09:20,000 --> 00:09:23,000
if we do have a notification to show.

176
00:09:23,000 --> 00:09:28,000
So in the end if notification is anything but undefined.

177
00:09:28,000 --> 00:09:32,000
Because if it is undefined there is nothing to show.

178
00:09:32,000 --> 00:09:35,000
So then here in this section, for example

179
00:09:35,000 --> 00:09:40,000
we can add a conditional content and check for notification.

180
00:09:40,000 --> 00:09:44,000
And if it's truthy, we rendered the notification component

181
00:09:44,000 --> 00:09:49,000
and we set status equal to notification dot status.

182
00:09:50,000 --> 00:09:55,000
And we set title equal to notification dot title.

183
00:09:55,000 --> 00:09:59,000
And we set message equal to notification dot message.

184
00:10:01,000 --> 00:10:06,000
Like this and status title and message are the props

185
00:10:06,000 --> 00:10:10,000
I'm expecting inside of that notification component.

186
00:10:10,000 --> 00:10:11,000
So we have to set them here.

187
00:10:13,000 --> 00:10:17,000
So that should now be working with all that work done.

188
00:10:17,000 --> 00:10:22,000
If we now reload and I again enter something here.

189
00:10:22,000 --> 00:10:25,000
Test for click sent message we see that

190
00:10:25,000 --> 00:10:28,000
sending state and then the success state.

191
00:10:28,000 --> 00:10:30,000
Now it never disappears at the moment

192
00:10:30,000 --> 00:10:33,000
but that's something we can also implement

193
00:10:33,000 --> 00:10:37,000
with help of useEffect as we saw earlier in the course.

194
00:10:37,000 --> 00:10:42,000
We can run a function whenever the request status changes

195
00:10:42,000 --> 00:10:45,000
and if it changed to success or error,

196
00:10:45,000 --> 00:10:49,000
then we want to reset it to undefined after three seconds

197
00:10:49,000 --> 00:10:53,000
let's say, and that will then re render this component

198
00:10:53,000 --> 00:10:56,000
and get rid of our notification.

199
00:10:56,000 --> 00:10:58,000
So here we can execute useEffect

200
00:10:58,000 --> 00:11:02,000
and define an effect function and the dependencies.

201
00:11:02,000 --> 00:11:06,000
And here in useEffect I wanna check if requests status

202
00:11:06,000 --> 00:11:09,000
is equal to pending,

203
00:11:09,000 --> 00:11:14,000
or if requests status is equal to error.

204
00:11:14,000 --> 00:11:18,000
So if it's either off the two, then if that is the case

205
00:11:18,000 --> 00:11:23,000
I want to set a timer to reset my request status.

206
00:11:24,000 --> 00:11:28,000
So then I'll set a timeout here, to three seconds

207
00:11:28,000 --> 00:11:33,000
and after three seconds, this function will execute

208
00:11:33,000 --> 00:11:38,000
and there I'll set request status to null.

209
00:11:39,000 --> 00:11:41,000
Reset it basically.

210
00:11:41,000 --> 00:11:46,000
We can also set request set request error to null here

211
00:11:46,000 --> 00:11:47,000
to reset this as well.

212
00:11:48,000 --> 00:11:53,000
And now request status is a dependency of useEffect,

213
00:11:53,000 --> 00:11:55,000
so that this effect function will re execute

214
00:11:55,000 --> 00:11:58,000
whenever the request status changes

215
00:11:58,000 --> 00:12:01,000
and only when that changes.

216
00:12:01,000 --> 00:12:02,000
So when we change entered email

217
00:12:02,000 --> 00:12:05,000
because we type into email field,

218
00:12:05,000 --> 00:12:07,000
we will not execute this again.

219
00:12:08,000 --> 00:12:11,000
Now if it executes again and we have a ongoing timer

220
00:12:11,000 --> 00:12:14,000
I wanna get rid of the existing timer though

221
00:12:14,000 --> 00:12:17,000
and hence I'll store a reference in a constant here

222
00:12:17,000 --> 00:12:19,000
and return that cleanup function

223
00:12:19,000 --> 00:12:24,000
where I call clear timeout and clear that timer.

224
00:12:24,000 --> 00:12:26,000
If that in fact should rerun

225
00:12:26,000 --> 00:12:28,000
whilst we have an ongoing timer.

226
00:12:29,000 --> 00:12:31,000
And of course here I don't wanna check

227
00:12:31,000 --> 00:12:34,000
for requests status pending but success I mean.

228
00:12:34,000 --> 00:12:36,000
So success or error.

229
00:12:36,000 --> 00:12:38,000
If the requests status is anything else

230
00:12:38,000 --> 00:12:40,000
we don't do anything.

231
00:12:40,000 --> 00:12:44,000
Okay. So now if we saved this, it should disappear.

232
00:12:44,000 --> 00:12:46,000
Let me also open up the Dev Tools

233
00:12:46,000 --> 00:12:49,000
to see if we got any errors there.

234
00:12:49,000 --> 00:12:52,000
Max, another try.

235
00:12:52,000 --> 00:12:54,000
Click send message,

236
00:12:54,000 --> 00:12:58,000
sending success and it disappears.

237
00:12:58,000 --> 00:13:01,000
And if I hammered this button and I sent multiple messages

238
00:13:01,000 --> 00:13:05,000
it's still only disappears once after three seconds

239
00:13:05,000 --> 00:13:06,000
because the timers get cleared.

240
00:13:08,000 --> 00:13:09,000
So that is working.

241
00:13:09,000 --> 00:13:13,000
All that data also did end up here on MongoDB.

242
00:13:13,000 --> 00:13:16,000
If we refresh we see all those messages here

243
00:13:16,000 --> 00:13:18,000
so that worked.

244
00:13:18,000 --> 00:13:20,000
And therefore now we all just show some feedback.

245
00:13:20,000 --> 00:13:24,000
Let's now see if it also works if something breaks.

246
00:13:24,000 --> 00:13:27,000
For this I'll go to the API route and break my credentials

247
00:13:27,000 --> 00:13:29,000
Like this saved as

248
00:13:29,000 --> 00:13:32,000
and try sending this request again.

249
00:13:32,000 --> 00:13:35,000
And then we have that error case here.

250
00:13:35,000 --> 00:13:38,000
Which also disappears after three second though.

251
00:13:38,000 --> 00:13:42,000
So that's also working and with that, let's fix it again.

252
00:13:42,000 --> 00:13:44,000
So this all works.

253
00:13:44,000 --> 00:13:45,000
As a last step,

254
00:13:45,000 --> 00:13:48,000
we maybe wanna clear the user input after it was sent

255
00:13:48,000 --> 00:13:51,000
and for this back in the contact form,

256
00:13:51,000 --> 00:13:55,000
we can basically go here

257
00:13:55,000 --> 00:13:58,000
where we set the request status to success

258
00:13:58,000 --> 00:14:00,000
and say that if the request is a success,

259
00:14:00,000 --> 00:14:03,000
we wanna clear what the user entered.

260
00:14:03,000 --> 00:14:05,000
Because then the message was sent

261
00:14:05,000 --> 00:14:08,000
and the input isn't needed anymore.

262
00:14:08,000 --> 00:14:10,000
So here we could set entered message

263
00:14:10,000 --> 00:14:11,000
to an empty string again,

264
00:14:11,000 --> 00:14:16,000
set entered email email to an empty string

265
00:14:16,000 --> 00:14:20,000
and set entered name to an empty string.

266
00:14:20,000 --> 00:14:23,000
Since we're binding all those state values

267
00:14:23,000 --> 00:14:28,000
back to the inputs here and here and here.

268
00:14:29,000 --> 00:14:30,000
If we change the state

269
00:14:30,000 --> 00:14:33,000
those changes will be reflected in the inputs.

270
00:14:34,000 --> 00:14:38,000
So if we do that, then if I reload again

271
00:14:38,000 --> 00:14:41,000
and again enter something here,

272
00:14:43,000 --> 00:14:45,000
A last try

273
00:14:45,000 --> 00:14:48,000
then if I click send message you'll see that

274
00:14:48,000 --> 00:14:51,000
the input disappears as soon as we have a success.

275
00:14:51,000 --> 00:14:55,000
And therefore now this is the final state

276
00:14:55,000 --> 00:15:00,000
of this contact form and of the overall blog.

277
00:15:00,000 --> 00:15:03,000
At least when it comes to what we see on the screen.

