
[ad_1]
Angular Auto-Save Forms | RxJS Operators
A Brief Guide to Creating Reactive and Template-Driven Forms with RxJs and Angular Material

In this article, we will study how to create auto-saving forms in Angular. We’ll be implementing this feature with all its whistles and bells, like turning it on and off, displaying snack-bar notifications, and more.
In this process, we are going to explore several RxJs operators. We will start by implementing the feature for reactive forms. Finally, we’ll see what changes are needed for template-driven forms.
So let’s get started!
Before we dive into the details, let’s take a quick look at the demo application.

The form has two input fields: the user’s first and last name. It has a “Save” button, which is enabled when the form is valid. Finally, if auto-save is enabled, a loading bar will appear at the bottom of the form whenever the user changes a value. Here is the code:
As you may have noticed, we use Angular Material. To install it, you just need to run: ng add @angular/material
,
It is quite easy to toggle the auto-saving feature.
First, we declare a boolean
variable autoSaveEnabled
In AppComponent
,
Then, we do a two-way bind using that variable [(ngModel)]="autoSaveEnabled"
Feather mat-slide-toggle
Element. Next, we pass the variable as an input UserProfile
The component, which contains the form.
We handle price changes autoSave
By applying the input property OnChanges
Lifecycle hook. we define ngOnChanges
A method to enable or disable auto-saving based on the value of the property (more on that soon).
The question we need to ask is “when”? When do we want the form to be saved automatically?
We want this to happen if all of the following conditions apply:
- Auto-save is enabled
- user changed a value
- form is valid
Condition #1 has already been applied in the previous section. The rest is implemented inside enableAutoSaving
way. So, let’s take a look.
In order to auto-save the form when the user changes a value (condition #2), we need to subscribe to the form valueChanges
Worth seeing
From official document, valueChanges
“A multicasting is an observable that emits an event each time the value of a control is passed in the UI or programmatically.”
- On line 1, we define
changesSubscription
To subscribe. We do the assignment on line 6. It will let us unsubscribe later when we want to disable this feature. - On lines 2 and 3, we define a
BehaviorSubject
and its corresponding observable to display or hide the loading bar. - On line 7, if the form is invalid, we filter and close any emitted values (condition #3). There is no point in saving invalid values.
- On line 8, given that the user has typed something to make the form valid, we emit
true
So the loading bar is displayed. - On line 9, we use
debounceTime
Operator with a time duration of 1000ms (=1 second). The observable will not emit until the user stops typing for more than a second. We give the user time to react, pause or think as they type. - Along the lines of 10-11, we use
switchMap
operator, which is a higher-order mapping operator. It sends user data from form tosaveUser
method ofUsersService
and expects to be seen. The method returns an observable, in whichswitchMap
Automatically subscribes and unsubscribes.
It is called “inner observable” because it is nested in another observable,valueChanges
, called the “outer observable”. Finally, if another value is emitted before the HTTP request is completed, thenswitchMap
cancels that request in favor of the new one. - On line 12, we use
finalize
operator on the inner observable. When this observable completes (normally or by an error), we emitfalse
To hide the loading bar. - on line 15, we end
subscribe
TovalueChanges
,
In saveUser
Below method, we are using catchError
and return EMPTY
To avoid propagation of any error from within (switchMap
) viewable to external (valueChanges
) Worth seeing.
If we let this happen, the observable will be complete, and we will have to subscribe again to hear the price changes.
Finally, when we need to disable the feature, we call disableAutoSaving
method to unsubscribe from changeValues
Worth seeing
Unfortunately, we haven’t done that yet.
Let’s say the user has filled out the form, and is now valid. Then, they repeatedly press the “Backspace” button until one of the fields becomes empty. The form becomes invalid, but the last change – the one with the last remaining character – is not canceled.
Yes, it’s a minor detail, but these details make a difference!
We need to see the change in the status of the form and act accordingly. To do this, we need to subscribe statusChanges
The form is observable.
- On lines 1 and 4, we define and set
statusSubscription
variable, just like we did withchangesSubscription
, - On line 5, we use
distinctUntilChanged
The operator allows only specific status values to be emitted when the form changes from valid to invalid and vice versa. - On line 6, we use
pairwise
Operator to sum the previous and current emitted values. On line 7, we usetap
operator to use this pair. - On lines 8-10, we call
disableAutoSaving
If the status of the form has changedVALID
ToINVALID
, it cancelschangesSubscription
, and thus no request is sent. problem fixed! - On lines 12-15, we enable auto-saving if the form is
VALID
And thischangesSubscription
Off, that is, if auto-saving was previously disabled. - On line 14, we call
updateValueAndValidity
clearly on the form. The first change that makes the form valid again will not be autosaved if we don’t. This is because this specific change happened before callingenableAutoSaving
How do we subscribechangeValues
Worth seeing - On line 17, we finally subscribe to the observable.
Finally, when we disable the auto-save feature, we should call disableStatusWatching
method to unsubscribe from statusChanges
Worth seeing
OK, now we’re done! I
As always, you can find a working demo at this stackblitz link or with code this github repository,
We saw how it works with reactive forms. Can we auto-save template-driven forms? of course we can! We just have to make some changes.
First, we need to import FormsModule
(if not already imported). by importing FormsModule
The NgForm
Instructions active on all <form>
tag. We don’t need to add any special selector.
But how do we listen to price and position changes? Well, we need to hold onto form.
We export the directive to a local template variable ngForm
as the key. We also register child controls using ngModel
And this name
Speciality
Next, we get the reference of the form by using @ViewChild
Decorator in component class. And all! Now we can use this context and do what we have seen so far.
Notice the strange syntax on line 19? No, this is not a typo.
NgForm
The instruction creates a top-level FormGroup
instance and binds it to a form to track the total form value and validation status. This FormGroup
can be accessed through example form
Property.
but NgForm
does not provide updateValueAndValidity
method or any other way to force the form to be updated. Hence, we are using this solution.
You can find the source code in a separate branch on both GitHub and StackBlitz in the previous link.
In this article, we demonstrated how to create auto-saving forms in Angular. During this we used and explained several RxJs operators. Lastly, we highlighted the differences between the implementation of Reactive and template-driven forms.
I hope you enjoyed this article and learned something new. If you did, follow me and subscribe to my newsletter for more content like this.
Thanks for reading. Stay tuned for more.
[ad_2]
Source link
#Create #AutoSaving #Forms #Angular