Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated:
1
00:00:02,150 --> 00:00:03,430
Now, it's of course, up to you
2
00:00:03,430 --> 00:00:06,280
which validation logic you wanna apply.
3
00:00:06,280 --> 00:00:08,500
I wanna keep it fairly simple.
4
00:00:08,500 --> 00:00:12,840
I wanna check that all my values are not empty
5
00:00:12,840 --> 00:00:15,160
and that the postal cost, let's say,
6
00:00:15,160 --> 00:00:17,653
is exactly five digits long.
7
00:00:19,010 --> 00:00:22,410
For this, I'll add a couple of helper functions here outside
8
00:00:22,410 --> 00:00:24,170
of the component function
9
00:00:24,170 --> 00:00:28,720
and the first one is the isEmpty helper function
10
00:00:28,720 --> 00:00:30,920
where I get a value and return true
11
00:00:30,920 --> 00:00:32,770
if value is empty.
12
00:00:32,770 --> 00:00:35,060
For that I call trim on value
13
00:00:35,060 --> 00:00:37,202
and then check if the length
14
00:00:37,202 --> 00:00:42,202
is equal to zero or simply if the trimmed string
15
00:00:42,620 --> 00:00:44,950
is equal to an empty string.
16
00:00:44,950 --> 00:00:47,540
And the second helper function, which I'll add here
17
00:00:47,540 --> 00:00:49,793
is the isNotFiveChars,
18
00:00:53,780 --> 00:00:55,170
whatever you wanna name it,
19
00:00:55,170 --> 00:00:56,710
where I get a value
20
00:00:56,710 --> 00:00:58,270
and I also trim this
21
00:00:58,270 --> 00:01:03,270
and I then check if the length is not equal to five.
22
00:01:03,380 --> 00:01:06,260
So if it's not five characters long.
23
00:01:06,260 --> 00:01:08,530
Now, these two helper functions can be used
24
00:01:08,530 --> 00:01:12,440
to now validate those entered values.
25
00:01:12,440 --> 00:01:15,603
So we can add a new constant, enteredNameIsValid,
26
00:01:17,060 --> 00:01:18,516
and that should be true
27
00:01:18,516 --> 00:01:20,930
if we can call isEmpty
28
00:01:20,930 --> 00:01:23,241
and pass in the enteredName
29
00:01:23,241 --> 00:01:25,420
and that then returns false.
30
00:01:25,420 --> 00:01:28,030
So if it it's not empty.
31
00:01:28,030 --> 00:01:30,113
So enteredNameIsValid is not isEmpty enteredName.
32
00:01:32,078 --> 00:01:35,080
If the enteredName is not empty, this is valid.
33
00:01:35,080 --> 00:01:37,520
And I'll repeat this for the street.
34
00:01:37,520 --> 00:01:38,870
So the enteredStreetIsValid
35
00:01:40,190 --> 00:01:41,813
if not isEmpty enteredStreet.
36
00:01:42,980 --> 00:01:45,840
And I'll repeat that for the city.
37
00:01:45,840 --> 00:01:47,200
So the enteredCityIsValid
38
00:01:48,660 --> 00:01:50,893
if not isEmpty enteredCity.
39
00:01:51,880 --> 00:01:56,730
And now for the enteredPostalCode to be valid,
40
00:01:56,730 --> 00:02:00,620
I will check if not isNotFiveChars
41
00:02:03,161 --> 00:02:05,350
for the enteredPostalCode.
42
00:02:05,350 --> 00:02:07,611
And that can be a bit confusing to read.
43
00:02:07,611 --> 00:02:09,380
Not isNot.
44
00:02:09,380 --> 00:02:13,160
We could also simply name this isFiveChars up there
45
00:02:13,160 --> 00:02:16,920
and check for equality like this.
46
00:02:16,920 --> 00:02:20,083
And then say it's valid if isFiveChars.
47
00:02:21,680 --> 00:02:24,680
That's the simpler form of writing this.
48
00:02:24,680 --> 00:02:26,980
We could do something similar for isEmpty
49
00:02:26,980 --> 00:02:28,610
and check for the opposite
50
00:02:28,610 --> 00:02:32,080
but I think that's not too tricky to understand.
51
00:02:32,080 --> 00:02:35,160
Now we've got these four helper variables here,
52
00:02:35,160 --> 00:02:36,710
which hold true or false.
53
00:02:36,710 --> 00:02:39,945
And now we can check if the overall form is valid
54
00:02:39,945 --> 00:02:42,900
by combining all these values.
55
00:02:42,900 --> 00:02:47,790
Only if all four constants here have a value of true,
56
00:02:47,790 --> 00:02:49,880
the overall form is valid.
57
00:02:49,880 --> 00:02:52,930
And I'm doing this very explicitly step by step here
58
00:02:52,930 --> 00:02:56,223
to make it as easy to follow along as possible.
59
00:02:57,150 --> 00:02:59,983
So now we can check if enteredNameIsValid.
60
00:03:00,880 --> 00:03:03,253
And enteredStreetIsValid.
61
00:03:04,580 --> 00:03:07,273
Combine that with enteredCityIsValid
62
00:03:08,690 --> 00:03:11,173
and last but not least with enteredPostalCodeIsValid.
63
00:03:13,350 --> 00:03:15,921
And only if all four together are true,
64
00:03:15,921 --> 00:03:18,320
formIsValid will be true.
65
00:03:18,320 --> 00:03:23,320
So if formIsValid, we can now submit the cart data
66
00:03:25,340 --> 00:03:28,300
because here we know that we gathered valid data
67
00:03:28,300 --> 00:03:29,963
and we can now proceed with that.
68
00:03:31,103 --> 00:03:35,480
But if the form is not valid, we wanna show an error.
69
00:03:35,480 --> 00:03:37,990
And therefore, that's what I'll actually check for here.
70
00:03:37,990 --> 00:03:40,420
I'll check if not formIsValid
71
00:03:40,420 --> 00:03:42,620
and then I wanna set an error
72
00:03:42,620 --> 00:03:45,330
and give some feedback to the user regarding
73
00:03:45,330 --> 00:03:47,330
what went wrong.
74
00:03:47,330 --> 00:03:48,590
For that, I will, first of all,
75
00:03:48,590 --> 00:03:52,120
return here to not continue with code execution
76
00:03:52,120 --> 00:03:56,600
because later I will submit the cart data here
77
00:03:56,600 --> 00:03:58,280
and I don't wanna reach that code
78
00:03:58,280 --> 00:03:59,693
if the form is invalid.
79
00:04:00,600 --> 00:04:02,880
But before we make it to this if check,
80
00:04:02,880 --> 00:04:07,210
I wanna update some state to give the user some feedback.
81
00:04:07,210 --> 00:04:09,790
And here I wanna manage four pieces of state
82
00:04:09,790 --> 00:04:12,000
since I have four inputs.
83
00:04:12,000 --> 00:04:15,080
And therefore, again we could use useReducer
84
00:04:15,080 --> 00:04:16,940
to kind of combine that all
85
00:04:16,940 --> 00:04:20,089
or to manage that with a reducer function in general
86
00:04:20,089 --> 00:04:23,950
but I will stick to useState here.
87
00:04:23,950 --> 00:04:26,410
You'll learn about useReducer and all of that
88
00:04:26,410 --> 00:04:28,433
in the forms module though.
89
00:04:29,750 --> 00:04:31,470
Now, we'll use useState
90
00:04:31,470 --> 00:04:35,103
and I will register a new state here with useState.
91
00:04:36,620 --> 00:04:39,540
And here, oops, not like this,
92
00:04:39,540 --> 00:04:42,590
instead some useState with useState.
93
00:04:42,590 --> 00:04:46,140
And here we could use four individual state slices
94
00:04:46,140 --> 00:04:48,757
or one combined state slice.
95
00:04:48,757 --> 00:04:52,000
And I'll go for the one combined state slice
96
00:04:52,000 --> 00:04:53,453
to mix things up.
97
00:04:54,590 --> 00:04:56,870
So here I have my formInputsValidity
98
00:04:59,900 --> 00:05:03,587
and a function to set the formInputsValidity.
99
00:05:05,910 --> 00:05:07,410
And now that will be an object
100
00:05:07,410 --> 00:05:11,410
where I have a name field, a street field,
101
00:05:11,410 --> 00:05:16,410
a city field and a postalCode field
102
00:05:16,440 --> 00:05:19,453
and now we need to give those fields some values.
103
00:05:20,390 --> 00:05:25,110
And I simply wanna have true or false as values here,
104
00:05:25,110 --> 00:05:28,970
determining whether the field is valid or not.
105
00:05:28,970 --> 00:05:31,510
And initially, I'll treat them as valid
106
00:05:31,510 --> 00:05:33,660
even though they technically aren't
107
00:05:33,660 --> 00:05:37,580
but I don't wanna show error messages at the beginning.
108
00:05:37,580 --> 00:05:40,250
Now, we could work with the touched state
109
00:05:40,250 --> 00:05:42,530
in addition to the validity state
110
00:05:42,530 --> 00:05:44,910
as we did it in the forms module
111
00:05:44,910 --> 00:05:47,250
but to keep things a bit shorter here
112
00:05:47,250 --> 00:05:51,740
and since we don't have an as elaborate validation approach
113
00:05:51,740 --> 00:05:53,620
as we did in the forms module,
114
00:05:53,620 --> 00:05:56,513
I will stick to a starting value of true here.
115
00:05:57,560 --> 00:06:01,270
Now the goal is to update the correct field
116
00:06:01,270 --> 00:06:03,560
for the different inputs here
117
00:06:03,560 --> 00:06:05,740
when we submitted the form
118
00:06:05,740 --> 00:06:07,780
to update those true values
119
00:06:07,780 --> 00:06:11,050
with the actual validity after we tried
120
00:06:11,050 --> 00:06:12,203
to submit the form.
121
00:06:13,680 --> 00:06:18,243
So for this, maybe before we even derive formIsValid,
122
00:06:19,920 --> 00:06:24,920
I will set the FormInputsValidity state to new object.
123
00:06:26,680 --> 00:06:29,020
And here I wanna set the name field
124
00:06:29,020 --> 00:06:31,237
to enteredNameIsValid,
125
00:06:32,450 --> 00:06:37,450
the street field to enteredStreetIsValid and so on.
126
00:06:37,750 --> 00:06:40,410
So I'll use those inferred validities,
127
00:06:40,410 --> 00:06:42,350
which we infer here
128
00:06:42,350 --> 00:06:46,433
as new values for the different keys in this state object.
129
00:06:47,470 --> 00:06:51,423
So here we have the enteredPostalCodeIsValid value.
130
00:06:52,800 --> 00:06:55,000
Now, we don't need the function form
131
00:06:55,000 --> 00:06:58,180
of this state updating function for updating here
132
00:06:58,180 --> 00:07:00,810
because I am overriding the entire state
133
00:07:00,810 --> 00:07:02,430
with a brand new object
134
00:07:02,430 --> 00:07:06,563
where I do assign new values to all my keys.
135
00:07:08,200 --> 00:07:09,750
And with that, we have information
136
00:07:09,750 --> 00:07:12,460
about the validity of the different fields.
137
00:07:12,460 --> 00:07:16,110
We can now utilize that in the JSX code down there,
138
00:07:16,110 --> 00:07:18,550
for example, to show an error message.
139
00:07:18,550 --> 00:07:20,110
Here for the name,
140
00:07:20,110 --> 00:07:25,110
we could check if formInputsValidity.name,
141
00:07:25,270 --> 00:07:27,150
so if we dive into the name field,
142
00:07:27,150 --> 00:07:29,640
if that is not true,
143
00:07:29,640 --> 00:07:31,370
hence the exclamation mark,
144
00:07:31,370 --> 00:07:33,480
then we wanna show a paragraph
145
00:07:33,480 --> 00:07:36,863
where we say please enter a valid name.
146
00:07:38,723 --> 00:07:40,000
Now, if we do that and save this,
147
00:07:40,000 --> 00:07:42,350
you'll see initially that's empty
148
00:07:42,350 --> 00:07:44,410
but if I try to confirm this,
149
00:07:44,410 --> 00:07:45,720
I now get this error
150
00:07:46,850 --> 00:07:48,880
and there, of course, we can now repeat that
151
00:07:48,880 --> 00:07:50,350
for all the inputs.
152
00:07:50,350 --> 00:07:53,200
So here we check .street
153
00:07:53,200 --> 00:07:56,793
and say please enter a valid street.
154
00:07:58,380 --> 00:08:01,370
And here we do it for the postal code.
155
00:08:01,370 --> 00:08:03,920
So .postalCode and then we say
156
00:08:03,920 --> 00:08:06,376
please enter a valid postal code,
157
00:08:06,376 --> 00:08:08,353
five characters long.
158
00:08:10,140 --> 00:08:11,280
And last but not least,
159
00:08:11,280 --> 00:08:13,830
here we check for .city
160
00:08:13,830 --> 00:08:15,873
and say please enter a valid city.
161
00:08:17,200 --> 00:08:19,710
I also prepared some extra styles
162
00:08:19,710 --> 00:08:22,420
in the Checkout.module.css file
163
00:08:22,420 --> 00:08:25,380
where I have an invalid class,
164
00:08:25,380 --> 00:08:27,730
which we can add to these divs here
165
00:08:27,730 --> 00:08:32,730
if an input is invalid to show extra error styles.
166
00:08:32,919 --> 00:08:34,990
So here on the name input, for example,
167
00:08:34,990 --> 00:08:38,429
instead of just adding the control class,
168
00:08:38,429 --> 00:08:40,880
I'll set up a template literal here
169
00:08:40,880 --> 00:08:44,780
to always inject the control class into the string
170
00:08:44,780 --> 00:08:48,440
but to also inject another class
171
00:08:48,440 --> 00:08:51,320
if that input should be invalid.
172
00:08:51,320 --> 00:08:55,640
So here we can check if formInputsValidity.name,
173
00:08:55,640 --> 00:09:00,090
if that is true, I don't wanna add any extra string
174
00:09:00,090 --> 00:09:01,810
to that class's string
175
00:09:01,810 --> 00:09:05,293
but if it's false, I wanna add classes.invalid here.
176
00:09:06,800 --> 00:09:09,870
With that, we add the extra invalid class
177
00:09:09,870 --> 00:09:13,733
to that list of classes if that input is not valid.
178
00:09:15,140 --> 00:09:19,230
And of course, instead of doing that in line here,
179
00:09:19,230 --> 00:09:20,910
we could also grab that code
180
00:09:20,910 --> 00:09:22,363
and add a new constant.
181
00:09:23,979 --> 00:09:27,890
nameControlClasses and store that value
182
00:09:27,890 --> 00:09:29,840
in that constant so that down there,
183
00:09:29,840 --> 00:09:33,653
we just point at nameControlClasses like this.
184
00:09:35,530 --> 00:09:38,400
That's an alternative way of doing that.
185
00:09:38,400 --> 00:09:40,500
And then now we can also repeat that
186
00:09:41,764 --> 00:09:43,610
for the street
187
00:09:44,790 --> 00:09:48,177
by checking for formInputsValidity.street
188
00:09:49,837 --> 00:09:51,650
and we do that for the other inputs for that as well.
189
00:09:51,650 --> 00:09:53,760
And we have some code duplication here
190
00:09:53,760 --> 00:09:56,020
but again, that's also something we talked about
191
00:09:56,020 --> 00:09:57,350
in the forms module
192
00:09:57,350 --> 00:09:59,700
and we could, for example, reduce that
193
00:09:59,700 --> 00:10:02,200
by creating a separate input component
194
00:10:02,200 --> 00:10:04,590
or reduce some other duplication
195
00:10:04,590 --> 00:10:07,680
by adding a custom forms hook, for example.
196
00:10:07,680 --> 00:10:10,110
For the moment here, I'll stick to this approach
197
00:10:10,110 --> 00:10:14,263
and hence, I'll add a postalCodeControlClasses constant
198
00:10:15,380 --> 00:10:18,480
where I check formInputsValidity.postalCode
199
00:10:19,410 --> 00:10:21,270
and then add another constant,
200
00:10:21,270 --> 00:10:23,240
the cityControlClasses
201
00:10:23,240 --> 00:10:27,000
where we check formInputsValidity.city.
202
00:10:27,000 --> 00:10:29,470
And now we just need to assign these constants
203
00:10:29,470 --> 00:10:31,200
to the different divs.
204
00:10:31,200 --> 00:10:33,570
So here for the street div,
205
00:10:33,570 --> 00:10:37,780
it's the streetControlClasses constant,
206
00:10:37,780 --> 00:10:40,594
which we assign as a value for className.
207
00:10:40,594 --> 00:10:45,594
Here for the postal code, it's the postalCodeControlClasses,
208
00:10:45,630 --> 00:10:48,460
which we assign as a value to className
209
00:10:48,460 --> 00:10:51,897
and for the city, it's the cityControlClasses.
210
00:10:54,262 --> 00:10:55,260
And with those changes made,
211
00:10:55,260 --> 00:10:57,540
if we save this, if I confirm this,
212
00:10:57,540 --> 00:10:59,226
we get a bunch of error styles
213
00:10:59,226 --> 00:11:02,180
and of course, if I enter something valid
214
00:11:02,180 --> 00:11:03,420
and I confirm this,
215
00:11:03,420 --> 00:11:05,813
it's not showing up for that input again.
216
00:11:11,738 --> 00:11:14,930
So you see that this now works.
217
00:11:14,930 --> 00:11:17,380
Now, feel free to definitely turn this
218
00:11:17,380 --> 00:11:21,310
into a more elaborate form validation here,
219
00:11:21,310 --> 00:11:24,010
for example, by adding a custom form hook
220
00:11:24,010 --> 00:11:26,410
or by also listening to the touch state
221
00:11:26,410 --> 00:11:29,530
and clearing errors as you start typing.
222
00:11:29,530 --> 00:11:32,570
We did dive into all of that in the form section.
223
00:11:32,570 --> 00:11:35,760
I just didn't want to bloat this module again
224
00:11:35,760 --> 00:11:37,790
with all the topics covered there.
225
00:11:37,790 --> 00:11:41,720
Instead, the goal was to pull out the essence
226
00:11:41,720 --> 00:11:45,713
of that module and just add some basic form validation here.
227
00:11:46,910 --> 00:11:48,626
And therefore, with all of that,
228
00:11:48,626 --> 00:11:52,190
we can now also confirm this without errors
229
00:11:52,190 --> 00:11:54,940
if we enter valid values.
230
00:11:54,940 --> 00:11:57,030
And hence now as a last step,
231
00:11:57,030 --> 00:11:59,350
let's make sure that those values
232
00:11:59,350 --> 00:12:02,823
are fetched and are sent to the backend.
17716
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.