Angular Forms Validation, updateOn: 'blur' & updateOn: 'submit' (Angular 5 edition)

In my previous post, I wrote about Asynchronous Validation in Angular's Reactive Forms Control. But that was when we were in the age of Angular 4, now a new age is upon us: age of Angular 5. With the new version, we have some new ways of doing validations in Angular forms. Since I won’t talk about everything from the beginning (How to define a form model, how to add validators etc.), consider this post as a continuation of my previous one. I’ll just show you the two new ways of doing Form Control validation.

To, give you a heads up, here is how our form model looked like:

this.forecastForm = this.fb.group({
        dateFormatted: new FormControl(this.forecast.dateFormatted, [Validators.required], [this.forecastValidators.existingDateValidator(this.forecast.dateFormatted)]),
        temperatureC: new FormControl(this.forecast.temperatureC, [Validators.required]),
        temperatureF: this.forecast.temperatureF,
        summary: this.forecast.summary
    });

Running the application will give you the following behavior,

Notice that the changes are immediately reflected in the form model and the validations are instant. That's cool but not the behavior you want when you have several Form Controls in your form model for performance reasons. But you can bypass this behavior using the updateOn: 'blur' and updateOn: 'submit' option.

So, the first one in our backpack is the updateOn: 'blur' option. Applying this will make the value of a Form Control subject to change with the blur event of a native input element associated with it.

Take the following code example,

this.forecastForm = new FormGroup({
        dateFormatted: new FormControl(this.forecast.dateFormatted, { validators: Validators.required, asyncValidators: [this.forecastValidators.existingDateValidator(this.forecast.dateFormatted)], updateOn: 'blur' }),
        temperatureC: new FormControl(this.forecast.temperatureC, [Validators.required]),
        temperatureF: new FormControl(this.forecast.temperatureF),
        summary: new FormControl(this.forecast.summary)
    });

Lot of things going on there. First, notice that we don't have this.fb.group(...) anymore (fb is a private instance of FormBuilder), because there is an issue regarding it. So, we have to go with the new FormGroup(...) instead. Also notice that now we have an options object as a second parameter of the FormControl where we can configure the synchronous, asynchronous validators and of course the updateOn: 'blur' option.

Rather than individually setting updateOn: 'blur', it can be set on parent Form Group for activating the option for every Form Control.

this.forecastForm = new FormGroup({
        dateFormatted: new FormControl(this.forecast.dateFormatted, { validators: Validators.required, asyncValidators: [this.forecastValidators.existingDateValidator(this.forecast.dateFormatted)] }),
        temperatureC: new FormControl(this.forecast.temperatureC, [Validators.required]),
        temperatureF: new FormControl(this.forecast.temperatureF),
        summary: new FormControl(this.forecast.summary)
    }, { updateOn: 'blur' });

If you run the application with the changes, you will get the following behavior. Notice that, value of a Form Control is only updating in the form model when we are blurred out of the input element.

Similarly the updateOn: 'submit' option will make the value/values of the Form Control(s) subjected to change on a submit event fired on the native form element. Following code shows you how to add the behavior for all the child Form Controls.

this.forecastForm = new FormGroup({
        dateFormatted: new FormControl(this.forecast.dateFormatted, { validators: Validators.required, asyncValidators: [this.forecastValidators.existingDateValidator(this.forecast.dateFormatted)] }),
        temperatureC: new FormControl(this.forecast.temperatureC, [Validators.required]),
        temperatureF: new FormControl(this.forecast.temperatureF),
        summary: new FormControl(this.forecast.summary)
    }, { updateOn: 'submit' });

And that's it! updateOn: 'blur' and updateOn: 'submit' are the options we were really craving for while working with Forms. Now it's available out of the box and you don't need any custom implementations. But remember, this options won't work while you are working with FormBuilder to build your form. As the Angular team mentioned that it will be available down the road.

https://github.com/fiyazbinhasan/ReactiveAsyncValidation