Join egghead, unlock knowledge.

Want more egghead?

This lesson is for members. Join us? Get access to all 3,000+ tutorials + a community with expert developers around the world.

Unlock This Lesson

Already subscribed? Sign In


    Validate Related Fields in an Elm Form

    Enrico BuonannoEnrico Buonanno

    One of the more complex aspects of validation is when you have to validate one field in relation to another (e.g.: that two passwords match, that check-out date is after check-in date, etc). In this lesson we see how to tackle such scenarios.



    Become a Member to view code

    You must be a Member to view code

    Access all courses and lessons, track your progress, gain confidence and expertise.

    Become a Member
    and unlock code for this lesson


    Instructor: 00:01 Next, I'm going to refactor this form to be a registration form. The most important thing will be to change the heading to be register.

    00:12 I'm going to change the model, remove the message, and replace it with a password field. I'm also going to need another field, which I'm going to call confirmPassword. The form will need to ensure that the two passwords match.

    00:28 Let me now refactor the form accordingly. Let me initialize these fields and create some message types for when the fields change. I handle these new message types, remove the validation code for the message, and then, I still want to use the applicative way to validate that both fields are OK.

    01:09 To do that, I need to add another parameter to the submit function for the confirmPassword field -- even though we ignore this field, because we assume that it's the same as the password itself -- and send the password in my payload.

    01:27 Next, let me update the view. Here, instead of the text error, I'll have another input. Let me just copy that for the confirmPassword field. Now, you can see that my form has been updated.

    02:05 Let's now look at validation for the password and confirmPassword fields. We'll check that the password is not empty and, furthermore, that it's a strong password. Let me define this function here. We're requiring the user to enter a password of six characters or more. Let me validate the password and update the password on the model.

    03:10 Now comes the more interesting part, which is to validate the confirmPassword field. Let me follow the pattern here. This is where we want to check that the passwords match. I could just write a validator inline that says, when you get a password, if that password is the same as the raw value of the password, then it's OK, else an error with a message, "The passwords don't match."

    04:18 Let me try that. If I say "hello1" and "hello2," indeed, we get "The passwords don't match." Let me also check that, if there's no password, we get the message, "Retype your password." These two validations on the confirmPassword field have the correct precedents.

    04:39 On one level, this seems to work. On the other hand, let me say that there's nothing here, here say "hello1," and validate. Here, there's no password, and we get a message that the passwords don't match. You might feel that if this is not valid in the first place, then why perform a validation to compare it with something else?

    05:02 The other problem is that here we're using the raw value, which might not be appropriate, for example, if we were comparing two ints. Rather than the raw value, we would like to use the password field in itself. What we would like to do is have a way that says validate that the password is equal to password. Otherwise, show this error.

    05:30 Let me open my validation module, and let me see if I could define such a function. What will be the signature for this? We know that what we want to return is a validator fromAtoA, and then, we have an error message. We have a field of A, and let's see how we could go about implementing this.

    06:00 This is the other field, and then, we have the error message. We want to return a validator, something that will take an A. We can switch on the validity of the other field. We could say, if it's valid, then it contains an A. I have to call this one A1 and this one A2. In this case, I can say that if A1 equals A1, then A2, else an error with the given error message.

    06:44 If the other field is invalid or not validated, then I don't have an A to compare it to. I'm just going to return A2. In other words, I'm not going to apply this validation. There's no point comparing to another thing when that other thing is invalid. Here, I forgot to put a type parameter. This has a raw value.

    07:10 Let me test this. Let's say "hello1" and "hello1." There are no errors, as far as the passwords go. If I say "hello" and "hello1," then this goes to invalid. See that we don't get the mismatch error, which seems to be fine, because the user is going to have to fix this first. If I say "hello2," then, of course, the passwords don't match. If I fix hello2, then validation passes.