Instructor: In the last section, we spoke a little bit
about the validation helper, inside of reduxForm.
Remember, all we have
to do is create a new function called Validate,
we'll pass it to the reduxForm helper,
and then whenever a user makes a change to the form,
or tries to submit the form,
our validate function will be called.
Let's see what this looks like in practice,
and I think it'll help with the understanding.
So the first thing we'll do is create our function validate.
Now remember, like I said, the validate function is going
to be called with all the properties of our form,
so all their field names
and the values of the fields as well.
So I'm going to call this argument just formProps.
The first thing we do inside any validate function,
is we make a new object called errors.
And so this is going to be the new object that's gonna
contain any errors that our fields might
be containing right now.
By default,
we always want to simply return our error's object.
Even if it ends up not adding any fields on here,
if we don't add any error messages whatsoever to the user,
we always just end up returning an empty object here,
saying hey, there, you know, here's an empty object.
There were no errors.
Go ahead and submit the form if you like.
So, before we go any further, let's add a console.log,
and just look at the formProps,
and kind of see what they look like,
and what's happening behind the scenes.
One last thing before we test this
out in the browser though,
we have tell reduxForm
to actually use this validate function.
To tell reduxForm to use the validate function,
we are just going to add it as another property
to the reduxForm configuration object.
So I'm going to add a comma after fields,
and then we'll add validate: validate.
Now as you might imagine,
we've got identical key and value here,
so we can condense this down with a little bit of ES6,
to simply be validate, like so.
Alright, let's give this a shot in the browser,
and see what it looks like.
I'm going to open up my terminal, use my console.
I'm going to refresh the page,
and you'll see immediately the instant
that our form renders, we get that console log.
Meaning, the instant the form renders,
reduxForm is going to instantly do some validation for us.
It's going to try to validate the form as often as it can.
Now, when I click into the email field,
notice how it console logs again.
Basically, whenever you do just about anything in reduxForm,
it's going to attempt to validate your inputs here.
So, let's start typing.
I'm gonna say test@example.com,
and you'll notice that we've got this email:
test@example.com in here now.
I'll add a password.
Password.
And, sure enough, we've got email: test@example.com,
with a password of password,
and a password confirm of password as well.
So now we can use this information, these kind of formProps,
to do some validation.
Let's give it a shot.
So, remember the rule here,
if a particular field has an error associated with it,
we add a property of the same name to the errors object,
and the value for that property should be
whatever error message we want to show to the user.
So let's do a very simple case here.
We're going to say if formProps.password does not equal
formProps.passwordConfirm,
then I want to add an error message to the errors object.
I want to say errors.password equals Passwords must match.
So let's see what this looks like inside the browser.
I'm gonna refresh, and then I'm gonna start typing,
and you can see that, hey like, ya know,
well is it doing the validation,
we saw the console logs before,
but where's the error message?
So that's kind of the key here.
reduxForm makes it easy for us to kind of hook in
and do validation, but it's not,
it doesn't have any magic associated with it
that's going to kind of automatically show errors for us.
So, once we have done this validation, the errors are there,
they're in memory, you know, they're being tracked,
validation is happening, but we have
to actually show some component on the screen,
or some text on the screen, a little bit more manually,
to say, hey here is what the error message actually is.
So let's give a shot at that.
Back over inside of our form, I'm going
to find the password field right here,
and right underneath it,
so I've password label, password input,
I'm going to put curly braces, and then, I'm going to say,
inside of these curly braces, I want to put field.error.
Excuse me, password.error.
So remember, this password right here, is a reference
to the password helper coming from reduxForm.
Whenever we return an error on that errors object,
it's going to be automatically assigned
to the error property of the individual field.
So now let's see what this looks like inside the browser.
I'm gonna refresh the page, and then I'm gonna start typing
in here and you'll see instantly,
I get passwords do not match, er, excuse me,
passwords must match.
So let's trying to, I'm going to put in a password of 123,
and then for confirm password, I'm can put in 123 as well,
and then you can see that error message goes
away automatically.
So this definitely works, ya know,
we're definitely getting the validation here.
As soon as my form becomes invalid,
I get the error message popping back up.
One thing that's really annoying for our users though,
is that the instant they click in and start typing,
they're getting this error message.
And it's kind of like, okay, well hey,
I'm not done typing yet, I haven't actually filled
out the form, why don't you just hold on for a second,
and then you can do the validation.
So to handle that case, or to kind of delay,
showing a message to our user,
we can add in another little helper here,
kind of a little trick.
Let's put the code down for it and then we'll talk
about exactly what's going on.
So right before the password.error, I'm going to put
in password.touched &&, excuse me, &&
and then, a div with className of error, and password.error.
So I did a pretty good amount of coding here.
First I put in password.touched && password.error &&,
and then a div with className error,
and it contains the text password.error.
So before we talk about exactly what this code is doing,
let's test out in the browser, and just see what happens.
I'm gonna refresh the page, and now, when I start typing,
you'll notice that I don't immediately get any error message
popping up on the screen, which is definitely good,
just what I want.
Only when I actually click out of the component,
do I see the error message pop up.
So only when I actually click out,
does the error message start to pickup.
Let's refresh.
So I just refreshed the page.
I'm typing in again.
I don't get the error message
until I actually click out of the input field,
and then I see Passwords must match here.
So that's a little bit more of the behavior that I like,
but let's talk about exactly how we achieved it.
So, here's what's happening.
We've got this kind of multi-layer && statement here.
This is a little bit of a trick in JavaScript,
and it basically says, if this evaluates to true,
and this evaluates to true, and this evaluates to true,
then return the last value.
So that's what's happening here.
We're using a little bit of a JavaScript trick
with how it hands these Boolean operators.
So if the password field has been touched by the user,
in other words, if the user has clicked into the field,
and then clicked out, and that field has an error,
then return this div with a className of error
and text of password.error.
So that's giving us a little bit more
of the behavior we actually want here.
Only when the user clicks into the field,
and then clicks out, and there's an error,
then we want to show a div, that has an error message,
to our user.
There is one last little thing here,
I ended on a className of error here,
but you'll notice that our, excuse me,
you'll notice that the text we get is still black here,
and we should really show it as red to our users,
just to kind of indicate to them, hey like,
there's an error here, you need to take care of this.
So to do that, we're just gonna add on a little bit
of custom CSS.
Inside of our project directory,
I'm gonna find the style folder,
and I'm gonna open style.css.
Then inside of here,
we're just gonna add a very simple rule,
just says .error, color: red.
So now, let's give this a shot in the browser.
And if I put it in, now I've got nice red text,
to kind of tell the user, hey,
this thing is currently incorrect, or there's an error
with this field.
You should probably take care of this
before you try to move on.
So this is definitely a little bit more
of what our users expect to see here.
So this is looking pretty good.
Once we put in some text, it gets validated,
and then when it actually matches, the error goes away,
which is just what we expect.
Let's continue in the next section, where we'll add
in some more validation around just discerning
that an email and a password combination exists at all.
So let's take care of that in the next section.