FormManager pitfalls
Updating state property depending on other property using reactive forms
If you plan to update state property based on other form property for example: reset post code on house number change. When you type in hause number ipost code will reset but hause number input will remain unchanged. Please see code bellow
merge(
this.form.controls.address.controls.addressSelectItem!.valueChanges,
this.form.controls.address.controls.houseNr!.valueChanges,
)
.pipe(
safeTakeUntilDestroyed(this.destroyRef))
.subscribe(() => {
const addressSelectItemControl = this.form.controls.address.controls.addressSelectItem;
const houseNrControl = this.form.controls.address.controls.houseNr;
if (addressSelectItemControl?.dirty || houseNrControl?.dirty) {
this.actions.resetPostalCode();
}
});
// actions code
resetPostalCode() {
this.store.update((state) => {
state.data.address.postalCode = '';
});
}
Why did this happened? Because FormsManager has default debounceTime of 100ms before syncing form value to a state. Since post code state is updated before, so state update is synced first back to form with originl hause number value.
In order to fix that add debouncTime to code which will be greater that default FormsManager debounceTime
merge(
this.form.controls.address.controls.addressSelectItem!.valueChanges,
this.form.controls.address.controls.houseNr!.valueChanges,
)
.pipe(
debounceTime(150), // <----
distinctUntilChanged(),
safeTakeUntilDestroyed(this.destroyRef))
.subscribe(() => {
const addressSelectItemControl = this.form.controls.address.controls.addressSelectItem;
const houseNrControl = this.form.controls.address.controls.houseNr;
if (addressSelectItemControl?.dirty || houseNrControl?.dirty) {
this.actions.resetPostalCode();
}
});
If 150ms seems to slow for you, you hav ealways a possibility to provide different debounceTime to FormsManager
this.ngFormStateManager = this.actions.store.select(['data'])
.form.bind(this.form, {
emitEvent: true,
debounceTime: 50,
});
Last updated
Was this helpful?