1
00:00:03,000 --> 00:00:04,665
We're at the point where

2
00:00:04,665 --> 00:00:07,440
we're sending a login request to the API

3
00:00:07,440 --> 00:00:10,147
when the user submits the Sign In form,

4
00:00:10,785 --> 00:00:13,097
and this works fine if the user enters

5
00:00:13,097 --> 00:00:14,436
the right credentials,

6
00:00:14,996 --> 00:00:16,039
but if they don't

7
00:00:16,039 --> 00:00:17,878
the error will not be handled.

8
00:00:18,440 --> 00:00:20,513
So let's go and improve this in our code.

9
00:00:21,173 --> 00:00:24,090
We want to catch any errors that may occur

10
00:00:24,090 --> 00:00:25,549
when we call the API.

11
00:00:27,739 --> 00:00:29,315
And in this case we should

12
00:00:29,315 --> 00:00:31,923
display an informative message to the user.

13
00:00:32,484 --> 00:00:34,557
But let's think about how to do that.

14
00:00:35,057 --> 00:00:37,642
We could simply display some text here

15
00:00:37,642 --> 00:00:40,636
saying something like "Invalid credentials".

16
00:00:41,323 --> 00:00:43,550
And maybe we could add some styles

17
00:00:43,550 --> 00:00:44,926
to make the text red,

18
00:00:44,926 --> 00:00:46,957
because errors are usually red.

19
00:00:46,957 --> 00:00:50,036
But of course we only want to show that message

20
00:00:50,036 --> 00:00:52,656
if there was an error, not all the time.

21
00:00:53,418 --> 00:00:54,644
So we'll need to add

22
00:00:54,644 --> 00:00:57,095
another state variable to our component,

23
00:00:57,095 --> 00:00:58,443
let's call it "error".

24
00:01:00,251 --> 00:01:02,199
And this could be a boolean property

25
00:01:02,199 --> 00:01:03,606
that is initially "false".

26
00:01:04,161 --> 00:01:05,622
But if an error occurs

27
00:01:05,622 --> 00:01:08,745
we can call "setError" and change it to "true".

28
00:01:08,745 --> 00:01:11,535
Incidentally, I'm catching all errors here

29
00:01:11,535 --> 00:01:12,731
to keep it simple,

30
00:01:12,731 --> 00:01:14,592
but ideally we should handle

31
00:01:14,592 --> 00:01:16,518
different errors differently.

32
00:01:16,518 --> 00:01:18,312
Like, if the request failed

33
00:01:18,312 --> 00:01:20,903
because we couldn't connect to the API,

34
00:01:20,903 --> 00:01:23,628
then we could display a different message

35
00:01:23,628 --> 00:01:25,887
rather than "Invalid credentials".

36
00:01:26,984 --> 00:01:29,716
Anyway, once we set that "error" flag,

37
00:01:29,716 --> 00:01:32,664
we can conditionally display this message

38
00:01:32,664 --> 00:01:34,461
only if the flag is true.

39
00:01:36,251 --> 00:01:39,093
This way there is no error message to begin with,

40
00:01:40,784 --> 00:01:42,949
but if we enter the wrong password

41
00:01:42,949 --> 00:01:46,134
at that point we see "Invalid credentials" in red.

42
00:01:46,698 --> 00:01:48,717
So far so good, but what happens

43
00:01:48,717 --> 00:01:50,863
if we type the right password now?

44
00:01:51,427 --> 00:01:53,199
The error message never goes away.

45
00:01:53,699 --> 00:01:55,523
That's because we're setting

46
00:01:55,523 --> 00:01:57,283
the "error" to "true" here,

47
00:01:57,283 --> 00:01:59,433
but we never reset it to "false".

48
00:02:00,064 --> 00:02:01,502
If the response is successful,

49
00:02:02,330 --> 00:02:04,144
or, even better, as soon as

50
00:02:04,144 --> 00:02:05,622
we re-submit the form,

51
00:02:06,190 --> 00:02:08,347
we should reset "error" to "false".

52
00:02:09,122 --> 00:02:11,087
This way when we click "Sign In"

53
00:02:11,087 --> 00:02:12,805
the error message goes away.

54
00:02:13,367 --> 00:02:15,225
Ok. We're handling the case

55
00:02:15,225 --> 00:02:17,153
where our API request fails,

56
00:02:17,153 --> 00:02:20,664
but there's another scenario we need to think about

57
00:02:20,664 --> 00:02:22,936
any time we make an HTTP request.

58
00:02:23,643 --> 00:02:25,665
And that's: what happens while

59
00:02:25,665 --> 00:02:27,486
the request is in progress?

60
00:02:28,054 --> 00:02:30,287
I'm going to add a helper function

61
00:02:30,287 --> 00:02:33,177
to simulate a slow response from the server.

62
00:02:33,177 --> 00:02:35,476
Since I'm running the Strapi server

63
00:02:35,476 --> 00:02:36,790
on my local machine,

64
00:02:36,790 --> 00:02:39,155
it will always respond very quickly,

65
00:02:39,155 --> 00:02:40,994
but in a real world scenario

66
00:02:40,994 --> 00:02:43,885
a user may be on a slow internet connection,

67
00:02:43,885 --> 00:02:45,790
so there could be some delay.

68
00:02:46,750 --> 00:02:50,361
This "sleep" function takes a number of milliseconds,

69
00:02:50,361 --> 00:02:52,337
and will return a new Promise

70
00:02:52,337 --> 00:02:55,335
that will resolve after that amount of time.

71
00:02:55,972 --> 00:02:57,203
It's basically a way

72
00:02:57,203 --> 00:02:59,421
to turn "setTimeout" into a Promise,

73
00:03:00,172 --> 00:03:03,449
so that we can call "sleep" with say 2 seconds,

74
00:03:03,949 --> 00:03:05,384
and then simply "await"

75
00:03:05,384 --> 00:03:07,380
for that amount of time to pass.

76
00:03:07,943 --> 00:03:10,360
This introduce an artificial delay

77
00:03:10,360 --> 00:03:12,350
when making the API request.

78
00:03:12,922 --> 00:03:15,483
And it means that when we click "Sign In"

79
00:03:15,483 --> 00:03:16,920
nothing seems to happen

80
00:03:16,920 --> 00:03:18,731
so I will try clicking again,

81
00:03:18,731 --> 00:03:20,855
because I'm a very impatient user.

82
00:03:21,543 --> 00:03:23,133
And the result is that

83
00:03:23,133 --> 00:03:26,676
I've actually triggered 3 separate HTTP requests,

84
00:03:26,676 --> 00:03:29,352
because I clicked the button 3 times.

85
00:03:29,997 --> 00:03:32,913
Ideally as soon as the user clicks "Sign In"

86
00:03:32,913 --> 00:03:34,836
we should disable this button

87
00:03:34,836 --> 00:03:37,885
until we receive the response from the server.

88
00:03:38,518 --> 00:03:40,258
And to do that we would need

89
00:03:40,258 --> 00:03:42,681
another state variable to keep track of

90
00:03:42,681 --> 00:03:45,913
whether we are "loading" a response from the server.

91
00:03:47,851 --> 00:03:50,612
And if "loading" is true we should disable

92
00:03:50,612 --> 00:03:51,796
the submit button.

93
00:03:52,362 --> 00:03:54,057
But if you think about it

94
00:03:54,057 --> 00:03:56,906
this "loading" state and the "error" state

95
00:03:56,906 --> 00:03:57,992
go hand in hand.

96
00:03:58,628 --> 00:04:01,795
We'll need to update both variables at the same time,

97
00:04:01,795 --> 00:04:04,066
depending on the state of the request.

98
00:04:04,626 --> 00:04:06,655
So we could change this to be

99
00:04:06,655 --> 00:04:09,035
a single variable called "status",

100
00:04:09,605 --> 00:04:13,035
that is an object containing a "loading" property

101
00:04:13,035 --> 00:04:14,715
and an "error" property.

102
00:04:15,871 --> 00:04:17,944
Both of which will be "false" initially,

103
00:04:18,444 --> 00:04:20,254
now we have an error because,

104
00:04:20,254 --> 00:04:22,627
the "error" variable no longer exists.

105
00:04:23,189 --> 00:04:25,463
It should be "status.error" now.

106
00:04:27,656 --> 00:04:30,683
Anyway, when we start a new HTTP request

107
00:04:30,683 --> 00:04:32,727
we should call "setStatus",

108
00:04:33,302 --> 00:04:34,925
and set "loading" to "true",

109
00:04:34,925 --> 00:04:37,591
because we're waiting for the server response,

110
00:04:38,149 --> 00:04:39,755
and "error" to false,

111
00:04:39,755 --> 00:04:41,515
since we don't know yet

112
00:04:41,515 --> 00:04:44,346
if this request will fail or succeed.

113
00:04:45,000 --> 00:04:46,977
Then when we get a response,

114
00:04:46,977 --> 00:04:48,247
if it's successful

115
00:04:48,247 --> 00:04:50,789
we want to set "loading" to "false",

116
00:04:50,789 --> 00:04:53,261
and leave "error" to false as well.

117
00:04:53,973 --> 00:04:55,726
While if we get an error then

118
00:04:55,726 --> 00:04:57,662
"loading" will still be "false",

119
00:04:57,662 --> 00:04:59,416
but "error" should be "true".

120
00:05:00,037 --> 00:05:02,425
Now we want to disable the button

121
00:05:02,425 --> 00:05:04,596
if the request is in progress.

122
00:05:04,596 --> 00:05:06,912
So let's check "status.loading",

123
00:05:07,557 --> 00:05:09,839
and to keep it simple, in this case

124
00:05:09,839 --> 00:05:12,317
I'll just show a "Loading..." message,

125
00:05:12,317 --> 00:05:14,926
even though it would be nicer to display

126
00:05:14,926 --> 00:05:18,056
some kind of progress indicator, like a spinner.

127
00:05:18,752 --> 00:05:20,324
While if "loading" is false

128
00:05:20,324 --> 00:05:22,303
then we can display this "Button".

129
00:05:24,384 --> 00:05:25,622
Let's see how this works.

130
00:05:26,185 --> 00:05:28,394
I'll have to re-enter the usual email address.

131
00:05:29,218 --> 00:05:31,798
Let's start with an incorrect password.

132
00:05:31,798 --> 00:05:34,113
And this time the button disappears

133
00:05:34,113 --> 00:05:36,561
so we cannot click it multiple times.

134
00:05:36,561 --> 00:05:37,950
And eventually we see

135
00:05:37,950 --> 00:05:40,200
the "Invalid Credentials" message.

136
00:05:40,965 --> 00:05:42,583
Now, let me clear the logs

137
00:05:42,583 --> 00:05:44,512
and type in the right password.

138
00:05:45,865 --> 00:05:46,685
It's loading.

139
00:05:47,898 --> 00:05:49,057
And after the delay

140
00:05:49,057 --> 00:05:51,680
we see the successful response in the logs.

141
00:05:52,242 --> 00:05:54,579
Ok. So this is how we can handle

142
00:05:54,579 --> 00:05:57,209
the "loading" and "error" conditions

143
00:05:57,209 --> 00:05:59,182
when making an API request.

144
00:05:59,182 --> 00:06:02,031
Note that all these different scenarios

145
00:06:02,031 --> 00:06:05,100
are the same when making any HTTP request,

146
00:06:05,100 --> 00:06:07,876
so we could actually extract this code

147
00:06:07,876 --> 00:06:10,287
into some sort of reusable logic,

148
00:06:10,287 --> 00:06:12,552
and in fact later in the course

149
00:06:12,552 --> 00:06:15,109
we'll use a library that simplifies

150
00:06:15,109 --> 00:06:16,497
some of this stuff.

151
00:06:17,655 --> 00:06:19,323
Anyway, before I forget

152
00:06:19,323 --> 00:06:21,717
let me remove this delay we added

153
00:06:21,717 --> 00:06:24,110
just to simulate a slow response.

154
00:06:24,756 --> 00:06:27,687
Let's quickly test that the app still works.

155
00:06:27,687 --> 00:06:28,487
That's good.

156
00:06:28,487 --> 00:06:31,285
The next step will be to decide what to do

157
00:06:31,285 --> 00:06:33,284
after we successfully sign in.

158
00:06:33,284 --> 00:06:35,083
What should we do with this

159
00:06:35,083 --> 00:06:37,615
JSON web token returned by the server?

160
00:06:37,615 --> 00:06:40,281
We'll talk about that in the next video.

