Essential Angular Form APIs You Should Know
Angular reactive forms is a powerful module for managing our forms in web applications but sometimes to solve particular issue we may implement some unnecessary code without realizing there are already builtin solutions available. In this article we are going to review some of them.
emitEvent:
When we patchValue, setValue, enable or disable form we have additional option emitEvent, onlySelf to pass as parameter.
emitEvent is an event triggered when our form value or status changes. Hence in official documentation:
*emitEvent: When true or not supplied (the default), both the `statusChanges` and `valueChanges` observables emit events with
the latest status and value when the control value is updated
So basically when we call setValue, patchValue, disable, enable control it triggers value change by default.
Use case:
Assume you have a custom form control which implements ControlValueAccessor. You have listener on parent whenever form value changes, trigger update data api. When you change form value from parent and in order to refect this change on custom control you implement this below method:
public writeValue(newValue: number): void {
this.value = newValue;
this.streetControl.patchValue(newValue, { emitEvent: false });
}
If we had not setted emitEvent to false, it would trigger valueChange so parent form would trigger unnecessary api which we want to avoid here.
updateValueAndValidity:
Before we dig into another option onlySelf, lets first understand updateValueAndValidatity method by official documentation:
* Recalculates the value and validation status of the control.
* By default, it also updates the value and validity of its ancestors.
* @param opts Configuration options determine how the control propagates changes and emits events
after updates and validity checks are applied.
* onlySelf: When true, only update this control. When false or not supplied, update all direct ancestors. Default is false.
* emitEvent: When true or not supplied (the default), both the `statusChanges` and `valueChanges` observables emit events
with the latest status and value when the control is updated. When false, no events are emitted.
updateValueAndValidity(opts: {onlySelf?: boolean, emitEvent?: boolean} = {}): void
In a nutshell, it recalculates the value and validation status of the control.It is triggered when control is first initialiazed or when we call patchValue, setValue, addControl, setControl or removeControl methods of form control.
Use case:
It is useful when we update validators of form control. Because when we update validators, it does not recalculate validation status by default, you need to call it additionally. For instance, assume we have a form called postalCode which has dynamic validator(here dependant on country field). When country is United States, we set validator max length 5 , in all other cases max length 7. In order to achive that, we would code like below DEMO:
When country value changed, we add and revalidate status of postal code. But there is small issue here, updateValueAndValidity will also trigger updateValueAndValidity method on parent form. See below code
What if we have asynchronous validators on parent? So we need to prevent this unnecessary check. This is where onlySelf option comes in.
onlySelf:
According to official documentation:
onlySelf: When true, each change only affects this control, and not its parent. Default is false.
Simply, when we call updateValueAndValidity this also triggers this change on parent. To solve issue in previous example, we need just to add new parameter: DEMO
this.addressForm.get('postalCode').updateValueAndValidity({ emitEvent: false, onlySelf: true });
There are also other essential methods available such as markAsTouched, markAsDirty but since they are straitforward I did not touch them. You can see screenshot below for definitions.
That’s all. Hope you found it helpful. Also please do not hesitate to contact me by the article responses or my Twitter ! Cheers!