In our latest project, we were facing some form-handling challenges. This post aims to decompose this issue and to show you our most used form-handling techniques. I hope these will help you make form handling with Angular much easier.
If I need to create forms, I prefer to use Angular’s Reactive Forms Module, which is quite self-explanatory in most cases.
The base building blocks are the following:
There are two different types of forms in the application: one with a submit button and one with auto-save functionality. I will show you the differences from a UX perspective and why we do it this way.
In this type of form, every input has a clean appearance in the beginning. The main question is: When should we inform the user if the filing contains an error?
If you display all the errors initially, the user can get frustrated, so that’s not an option. In this case, we try to follow the following rules:
The application will provide clear information to the user about what is wrong with the form, for example, there is a red border around the input fields and an error message below the fields. Once the input is corrected, the notification disappears.
The rules from the previous example don’t work well in this situation since there aren’t any submit buttons that we can click to trigger the validation messages.
You also shouldn’t block the auto-save functionality until the form is filled out correctly.
Imagine you have a form with 60 required fields, and you’ve filled out the first 50 when the browser crashes. When the user returns to the process, all the previous data should be available. So the rules are as follows:
Here is a simple auto-save functionality in Angular:
formGroup = this._fb.group({
name: ["", [Validators.required]]
});
constructor(private _fb: FormBuilder) {}
ngOnInit() {
this.formGroup.valueChanges
.pipe(
takeUntil(this._destroy$),
debounceTime(500),
concatMap(value => this.fakeSave(value)),
tap(console.log)
)
.subscribe();
}
fakeSave(value) {
return of(`Saved: ${JSON.stringify(value)}`).pipe(
tap(() => console.log("started")),
delay(1000)
);
}
There are some similarities in these two ways of form handling:
I hope following these rules can help everyone achieve a better, more consistent user experience in their applications. If you don’t follow the same rules, the most important thing is, BE CONSISTENT across the entire application. This will help the user understand what mistakes they made and understand how to fix that.
The full example repo is available at stackblitz.io.