Do you really want to create an observable for each input field in your form? The pattern I use is to have one observable for the model of the whole form, clone it for a view variable that you can then bind to and then have the submit handler of the form push the new model back to the service.
user$ = this.userService.user$;
save(user: User) {
this.userService.save(user);
}
and in the view
<form *ngIf="user$ | async | clone as user" #userForm="ngForm" (submit)="userForm.form.valid && save(user)">
<label>
Firstname
<input name="firstname" [(ngModel)]="user.firstname" required>
</label>
<label>
Lastname
<input name="lastname" [(ngModel)]="user.lastname" required>
</label>
<button>Save</button>
</form>
The clone pipe looks like this
export const clone = (obj: any) =>
Array.isArray(obj)
? obj.map(item => clone(item))
: obj instanceof Date
? new Date(obj.getTime())
: obj && typeof obj === 'object'
? Object.getOwnPropertyNames(obj).reduce((o, prop) => {
o[prop] = clone(obj[prop]);
return o;
}, {})
: obj;
import { Pipe, PipeTransform } from '@angular/core';
import { clone } from './clone';
@Pipe({
name: 'clone'
})
export class ClonePipe implements PipeTransform {
transform(value: any): any {
return clone(value);
}
}
I have done a write up on this pattern with my state management library here. https://medium.com/@adrianbrand/angular-state-management-with-rxcache-468a865fc3fb
myObservable.subscribe((myVar) => this.myVar = myVar)
andmyObserable | async
2. Learn how to extend Angular objects. I don't understand how decorators work and how to extend decorated objects. I'm picking ngModel to illustrate the problem I'm trying to solve but it's not really about ngModel at all. – Ashes