Adding a Loading State to the Post Form Submission Process
Guide Tasks
  • Read Tutorial
  • Watch Guide Video
Video locked
This video is viewable to users with a Bottega Bootcamp license

WEBVTT

1
00:00:00.560 --> 00:00:02.750
Now that our post form screen is working,

2
00:00:02.750 --> 00:00:05.770
and our users are able to create new records

3
00:00:05.770 --> 00:00:09.390
that are persisted and stored in the database.

4
00:00:09.390 --> 00:00:12.060
Now let's start to clean up our form a little bit.

5
00:00:12.060 --> 00:00:15.950
So in this guide, I wanna focus on two main things.

6
00:00:15.950 --> 00:00:18.230
I want to remove any debugging output

7
00:00:18.230 --> 00:00:22.050
from the screen here, such as placing the entire URL

8
00:00:22.050 --> 00:00:23.960
to the image in place.

9
00:00:23.960 --> 00:00:28.850
And then I also want to add a is submitting type of state.

10
00:00:28.850 --> 00:00:32.670
Because right now, if a user were to hit submit,

11
00:00:32.670 --> 00:00:35.540
nothing on the screen really looks like it's happening.

12
00:00:35.540 --> 00:00:37.380
And that's not a great experience.

13
00:00:37.380 --> 00:00:41.130
Imagine a scenario where the server is slow,

14
00:00:41.130 --> 00:00:44.860
and it takes a few seconds for that image to be set up.

15
00:00:44.860 --> 00:00:46.920
If nothing happens on the screen,

16
00:00:46.920 --> 00:00:50.090
most users are gonna think that something's broken,

17
00:00:50.090 --> 00:00:51.380
something's not working,

18
00:00:51.380 --> 00:00:54.160
and typically what they'll do is they'll just start pressing

19
00:00:54.160 --> 00:00:56.700
the button a bunch of times, which creates a problem

20
00:00:56.700 --> 00:00:59.060
because it's gonna create a bunch of different duplicate

21
00:00:59.060 --> 00:01:02.130
records, and it's just gonna be confusing

22
00:01:02.130 --> 00:01:03.910
at a bad user experience.

23
00:01:03.910 --> 00:01:05.660
So instead, I wanna populate

24
00:01:05.660 --> 00:01:08.580
the same thing we did in our authentication screen,

25
00:01:08.580 --> 00:01:10.840
so that when a user clicks Submit,

26
00:01:10.840 --> 00:01:12.580
the button becomes disabled.

27
00:01:12.580 --> 00:01:16.310
And then from there, they're told that a process

28
00:01:16.310 --> 00:01:17.170
is happening.

29
00:01:17.170 --> 00:01:19.610
In this case the post is being submitted.

30
00:01:19.610 --> 00:01:21.900
So let's build that out in this guide

31
00:01:21.900 --> 00:01:24.820
I'm first gonna scroll all the way down to the bottom

32
00:01:24.820 --> 00:01:27.180
and let's get rid of that debugging text.

33
00:01:27.180 --> 00:01:30.640
So I'm gonna get rid of everything there.

34
00:01:30.640 --> 00:01:32.210
And I'll hit save.

35
00:01:32.210 --> 00:01:34.510
So now when we upload an image,

36
00:01:34.510 --> 00:01:36.910
it's not going to print out that URL.

37
00:01:36.910 --> 00:01:41.910
Now let's go and let's add our is submitting piece of state.

38
00:01:42.150 --> 00:01:45.350
So I'm just gonna copy here on line 12,

39
00:01:45.350 --> 00:01:49.680
and I'm gonna change the first name to be is submitting

40
00:01:50.680 --> 00:01:54.340
and I'm gonna create our setter so that it says set

41
00:01:54.340 --> 00:01:58.650
is submitting and then for our default state,

42
00:01:58.650 --> 00:02:00.910
this is going to start off as false,

43
00:02:00.910 --> 00:02:03.520
because when this component loads up when the post form

44
00:02:03.520 --> 00:02:06.960
screen loads, it's not loading anything.

45
00:02:06.960 --> 00:02:08.960
So we don't want this to be true,

46
00:02:08.960 --> 00:02:11.230
we want it to be false by default.

47
00:02:11.230 --> 00:02:13.940
Now, when do we want this to be triggered?

48
00:02:13.940 --> 00:02:17.750
Or when the user presses submit, that's when we want

49
00:02:17.750 --> 00:02:20.130
all of this just start occurring.

50
00:02:20.130 --> 00:02:23.560
So I'm gonna copy where it says set is submitting.

51
00:02:23.560 --> 00:02:27.240
And in our handle submit function here.

52
00:02:27.240 --> 00:02:29.220
Right below where we get the token,

53
00:02:29.220 --> 00:02:31.900
I'm gonna say set is submitting.

54
00:02:31.900 --> 00:02:34.870
And I'm gonna make this be true.

55
00:02:34.870 --> 00:02:39.090
Then I'm going to come down here and in our response

56
00:02:39.090 --> 00:02:40.530
right after the console log,

57
00:02:40.530 --> 00:02:44.270
I'm gonna say set as submitting, set that equal to false.

58
00:02:44.270 --> 00:02:46.680
And then I'm also gonna copy that right below

59
00:02:46.680 --> 00:02:48.760
our error message right here.

60
00:02:48.760 --> 00:02:51.790
Now all of this should work.

61
00:02:51.790 --> 00:02:54.440
Now one other thing I remembered in the last guide,

62
00:02:54.440 --> 00:02:57.540
I told you, I was gonna walk through the headers

63
00:02:57.540 --> 00:02:59.380
here just a little bit more.

64
00:02:59.380 --> 00:03:02.440
So let's take quick pause, and let's talk about that.

65
00:03:02.440 --> 00:03:06.360
So this is the first time we've used our headers

66
00:03:06.360 --> 00:03:09.270
like this where we have headers, authorization

67
00:03:09.270 --> 00:03:12.600
and then we also have except in content type.

68
00:03:12.600 --> 00:03:16.580
Really, the only reason why we need to do that is because

69
00:03:16.580 --> 00:03:21.580
the API can't really understand the way images are passed

70
00:03:21.860 --> 00:03:25.670
if it's not told to expect that an image is gonna

71
00:03:25.670 --> 00:03:26.660
be sent up.

72
00:03:26.660 --> 00:03:29.600
So a common thing you'll see in forms

73
00:03:29.600 --> 00:03:31.380
whenever you're working with react,

74
00:03:31.380 --> 00:03:33.850
or any type of JavaScript application

75
00:03:33.850 --> 00:03:36.640
if you're sending some type of media,

76
00:03:36.640 --> 00:03:41.640
the key word here is multi part form data.

77
00:03:41.790 --> 00:03:43.790
So what that's doing is it's saying,

78
00:03:43.790 --> 00:03:47.380
hey, we're creating this form data object,

79
00:03:47.380 --> 00:03:48.330
we're wrapping it up.

80
00:03:48.330 --> 00:03:51.500
We're structuring it exactly like how we did in our build

81
00:03:51.500 --> 00:03:52.820
form function.

82
00:03:52.820 --> 00:03:57.730
And then here, we're simply letting the API know

83
00:03:57.730 --> 00:03:59.320
what is about to occur.

84
00:03:59.320 --> 00:04:01.380
It's almost kind of like we're creating

85
00:04:01.380 --> 00:04:03.880
a little bit of a contract with the API,

86
00:04:03.880 --> 00:04:06.840
we're saying, hey, I have something for you.

87
00:04:06.840 --> 00:04:10.430
And here are the rules that I followed,

88
00:04:10.430 --> 00:04:14.640
I have put together my authorization rules,

89
00:04:14.640 --> 00:04:18.430
then I'm telling you that you're gonna have to accept

90
00:04:18.430 --> 00:04:20.830
JSON data for this to work.

91
00:04:20.830 --> 00:04:24.040
And then lastly, I'm telling you the content type,

92
00:04:24.040 --> 00:04:26.130
I'm telling you, I'm sending you something

93
00:04:26.130 --> 00:04:29.880
that is going to be multi part form data.

94
00:04:29.880 --> 00:04:33.370
From there, the server's really good at being able to pick

95
00:04:33.370 --> 00:04:35.540
up on each one of those rules,

96
00:04:35.540 --> 00:04:38.230
and then adjusting accordingly.

97
00:04:38.230 --> 00:04:40.330
So that's what the headers are doing here.

98
00:04:40.330 --> 00:04:42.470
I just wanted to make sure that that was clear

99
00:04:42.470 --> 00:04:44.230
before we moved on.

100
00:04:44.230 --> 00:04:48.260
Okay, so back to adding our submitting state.

101
00:04:48.260 --> 00:04:51.060
So just to kinda walk through what's happening

102
00:04:51.060 --> 00:04:54.290
when a user clicks the submit button,

103
00:04:54.290 --> 00:04:57.700
they are going to trigger this function handle Submit.

104
00:04:57.700 --> 00:04:59.250
We're going to get the token

105
00:04:59.250 --> 00:05:02.830
and then we're immediately gonna say set is submitting

106
00:05:02.830 --> 00:05:07.830
to true that means we're activating our loading state.

107
00:05:08.270 --> 00:05:11.450
At this state this is where I want this button

108
00:05:11.450 --> 00:05:15.230
to no longer be clickable, I want it to be disabled

109
00:05:15.230 --> 00:05:18.180
and I want it to say instead of just saying submit,

110
00:05:18.180 --> 00:05:19.750
I want it to say something else.

111
00:05:19.750 --> 00:05:22.800
I won't say submitting, then what we're doing

112
00:05:22.800 --> 00:05:25.550
is we're waiting for the API to get back to us.

113
00:05:25.550 --> 00:05:29.530
Whether it gets back successfully, or if there was an error,

114
00:05:29.530 --> 00:05:32.550
I want to set in submitting to false.

115
00:05:32.550 --> 00:05:36.840
Because if there's an error, so let's say that the user

116
00:05:36.840 --> 00:05:40.640
typed in something invalid, or they tried to upload a video

117
00:05:40.640 --> 00:05:43.720
instead of an image, the server is going to return back

118
00:05:43.720 --> 00:05:46.140
an error message and so we want to make sure

119
00:05:46.140 --> 00:05:49.660
that we allow the user to correct their mistake

120
00:05:49.660 --> 00:05:51.700
and to resubmit.

121
00:05:51.700 --> 00:05:54.640
So that's why we have to set is submitting false

122
00:05:54.640 --> 00:05:57.910
here in both the response and in the air.

123
00:05:57.910 --> 00:06:02.480
Now later on in a future guide we're going to add a redirect

124
00:06:02.480 --> 00:06:05.210
that occurs right here, where we're gonna say,

125
00:06:05.210 --> 00:06:07.560
Okay, did that post get created?

126
00:06:07.560 --> 00:06:10.720
If it did, let's take the user to a different screen.

127
00:06:10.720 --> 00:06:13.440
And we'll walk through how to do that later on.

128
00:06:13.440 --> 00:06:15.770
So that's the handle submit portion.

129
00:06:15.770 --> 00:06:18.410
Now let's customize our button.

130
00:06:18.410 --> 00:06:22.060
Now I've noticed I took a look at the button component.

131
00:06:22.060 --> 00:06:25.440
And I think we can refactor the button a little bit

132
00:06:25.440 --> 00:06:26.930
to make this even better.

133
00:06:26.930 --> 00:06:28.690
But I'm gonna show you what this workflow

134
00:06:28.690 --> 00:06:31.920
is gonna look like, before we do that refactor.

135
00:06:31.920 --> 00:06:35.330
We're gonna say, I've duplicated the button component,

136
00:06:35.330 --> 00:06:38.240
and I'm gonna add a curly bracket here and say,

137
00:06:38.240 --> 00:06:42.570
if is submitting, and so I'm gonna use a ternary operator.

138
00:06:42.570 --> 00:06:46.180
So I'm gonna say if we're in a submitting state,

139
00:06:46.180 --> 00:06:48.839
so if this is true, if that piece of state is true,

140
00:06:48.839 --> 00:06:53.640
question mark, then I want you to show this type of button.

141
00:06:53.640 --> 00:06:56.270
This is gonna be our disabled button.

142
00:06:56.270 --> 00:07:00.480
And then if not so at the very end of that button component,

143
00:07:00.480 --> 00:07:03.950
I'm gonna add a colon here and then at the very end

144
00:07:03.950 --> 00:07:07.640
of the last button call all and curly brackets.

145
00:07:07.640 --> 00:07:11.930
So if you hit save prettier, we'll format it nicely for us.

146
00:07:11.930 --> 00:07:14.480
So we're saying if is submitting is true,

147
00:07:14.480 --> 00:07:17.120
so in other words if the user is clicking that button,

148
00:07:17.120 --> 00:07:19.510
then I want you to show one type of button,

149
00:07:19.510 --> 00:07:22.370
and if it's not true, then I want you to show

150
00:07:22.370 --> 00:07:23.830
this other button.

151
00:07:23.830 --> 00:07:27.700
Now what we need to do here is to switch up the text

152
00:07:27.700 --> 00:07:30.450
and then also to make this disabled.

153
00:07:30.450 --> 00:07:34.010
Now if you notice back in our auth screen,

154
00:07:34.010 --> 00:07:35.840
if you switch to the auth screen,

155
00:07:35.840 --> 00:07:39.690
you can see right here that we're using a disabled button,

156
00:07:39.690 --> 00:07:43.720
but we still are passing the on press handler to it.

157
00:07:43.720 --> 00:07:46.250
Now this won't work because remember,

158
00:07:46.250 --> 00:07:48.583
if you look at our button component,

159
00:07:49.700 --> 00:07:52.910
if we are in a disabled state,

160
00:07:52.910 --> 00:07:56.290
then it's not really going to work.

161
00:07:56.290 --> 00:07:58.420
But it's still not a good idea

162
00:07:58.420 --> 00:08:00.344
because the user could still click on it.

163
00:08:00.344 --> 00:08:02.300
There could be some issues with it.

164
00:08:02.300 --> 00:08:04.720
So we can refactor our button component

165
00:08:04.720 --> 00:08:05.970
and make this better.

166
00:08:05.970 --> 00:08:08.570
And the way we could do that is by making

167
00:08:08.570 --> 00:08:11.410
on press optional here.

168
00:08:11.410 --> 00:08:14.040
So I'm gonna hit save and what this means

169
00:08:14.040 --> 00:08:18.340
is that when we do not pass an on press handler

170
00:08:18.340 --> 00:08:21.750
to the button component, then nothing is going to occur.

171
00:08:21.750 --> 00:08:23.800
And it's just is gonna make it cleaner.

172
00:08:23.800 --> 00:08:27.180
So if you look at the post form screen now,

173
00:08:27.180 --> 00:08:31.030
the is submitting true, I'm gonna say the text

174
00:08:31.030 --> 00:08:33.300
is gonna be submitting...

175
00:08:34.384 --> 00:08:38.670
And now I can remove this on press handler entirely

176
00:08:38.670 --> 00:08:43.560
and then pass in just disabled just like this.

177
00:08:43.560 --> 00:08:48.010
And so this is gonna give us a lot cleaner interface

178
00:08:48.010 --> 00:08:49.520
for working with the button.

179
00:08:49.520 --> 00:08:52.560
And now we can also go back to our auth screen

180
00:08:52.560 --> 00:08:55.040
and we can redo this one as well.

181
00:08:55.040 --> 00:08:57.980
So we still like that where it says is submitting,

182
00:08:57.980 --> 00:09:01.440
but now let's get rid of the on press handler.

183
00:09:01.440 --> 00:09:04.630
And anytime you have a prop that is a bullion

184
00:09:04.630 --> 00:09:07.150
and you want that value to be true,

185
00:09:07.150 --> 00:09:10.540
then you don't actually even have to pass in the equals

186
00:09:10.540 --> 00:09:13.440
and then curly brackets, you can just pass in the name

187
00:09:13.440 --> 00:09:17.010
of the prop itself and then react adjusts accordingly.

188
00:09:17.010 --> 00:09:20.300
So let's hit save here and it looks like everything

189
00:09:20.300 --> 00:09:21.133
there worked.

190
00:09:21.133 --> 00:09:24.630
So what we should expect now when we create a post,

191
00:09:24.630 --> 00:09:28.630
is this should switch to where it says submitting,

192
00:09:28.630 --> 00:09:30.560
it should change the color.

193
00:09:30.560 --> 00:09:33.680
And then from there it's gonna create that post

194
00:09:33.680 --> 00:09:36.480
and then it will switch back to this submit button

195
00:09:36.480 --> 00:09:38.490
whenever that's done successfully.

196
00:09:38.490 --> 00:09:40.890
And then we can go to the feed screen to see if that worked.

197
00:09:40.890 --> 00:09:45.890
So I'm gonna say testing looting States and put in some

198
00:09:46.540 --> 00:09:51.540
content and I'll pick an image and hit choose,

199
00:09:53.330 --> 00:09:57.060
and now if I press on submit,

200
00:09:57.060 --> 00:09:59.110
you'll see that now it says submitting.

201
00:09:59.110 --> 00:10:00.940
And then when that happened

202
00:10:00.940 --> 00:10:04.070
it came back and told us that it succeeded.

203
00:10:04.070 --> 00:10:06.210
And that's the reason why we switched back

204
00:10:06.210 --> 00:10:07.870
to this regular button.

205
00:10:07.870 --> 00:10:11.633
If you go back to the feed screen and hit refresh,

206
00:10:13.790 --> 00:10:16.540
now you'll see testing loading state worked,

207
00:10:16.540 --> 00:10:18.640
the one we created in the last guide work.

208
00:10:18.640 --> 00:10:20.950
So all of this is looking really good

209
00:10:20.950 --> 00:10:23.180
and now we have a loading state

210
00:10:23.180 --> 00:10:27.230
and we've also refactored a button component nicely,

211
00:10:27.230 --> 00:10:30.530
so that it can work in both a loading state,

212
00:10:30.530 --> 00:10:34.120
which means it's disabled and then a normal state

213
00:10:34.120 --> 00:10:37.000
and we've created a much cleaner interface

214
00:10:37.000 --> 00:10:40.010
for how to work with that button component now

215
00:10:40.010 --> 00:10:44.010
we're no longer passing in content that it doesn't need.

216
00:10:44.010 --> 00:10:47.310
So great job if you went through that, our form is starting

217
00:10:47.310 --> 00:10:50.800
to look good in the next guide, we're gonna start

218
00:10:50.800 --> 00:10:54.110
building out a new screen, which is gonna be our post

219
00:10:54.110 --> 00:10:57.360
details screen, which is gonna be where the user

220
00:10:57.360 --> 00:11:01.753
is redirected after they have successfully created a post.

Resources