Reputation: 9230
I have a form that updates an object directly like so
component.html
<input type="text" [(ngModel)]="user.name" />
<input type="text" [(ngModel)]="user.surname" />
<input type="text" [(ngModel)]="user.age" />
component.ts
user = {
name: null,
surname: null,
age: null
}
now in my component.html I have a save button that is in a child component
<app-save-btn [user]="user"></app-save-btn>
and in the app-save-btn
component I am listening for changes using OnChanges
@Input() user: User;
userForCompare: User;
ngOnChanges() {
if (!this.userForCompare) {
this.userForCompare = {...this.user};
}
console.log(this.userForCompare, this.user);
}
now my issue is, I get the first console log of the two user objects, but as I update further fields I no longer get change updates..
now I know that I could create seperate variables to hold each value, but I have like 30 field items so I dont want to change my implementation to much...
any help would be appreciated
Upvotes: 0
Views: 1377
Reputation: 6089
I would suggest creating a FormGroup
with Reactive Forms to manipulate your fields. Using FormBuilder.group()
you can create a form containing each for the property of the User
object... that way you would only need to pass form.value
to your child component.
Reactive form keeps the data model pure by providing it as an immutable data structure. Each time a change occurs to the form, the
FormControl
instance will not update the existing data model, it will return a new state (a new data model).
https://www.ibrahima-ndaw.com/blog/5-reasons-to-use-reactive-form/
Here is a live StackBlitz example using the code below:
https://stackblitz.com/edit/angular-stackoverflow-60424523
example.component.html
<form [formGroup]="form">
<input [formControlName]="'name'" />
<input [formControlName]="'surname'" />
<input [formControlName]="'age'" />
</form>
<app-save-btn [user]="form.value"></app-save-btn>
example.component.ts
import { Component, OnInit} from '@angular/core';
import { FormBuilder, FormGroup} from '@angular/forms';
@Component({ ... })
export class AppComponent implements OnInit {
form: FormGroup;
user: User = {
name: 'Initial name',
surname: 'Initial surname',
age: 99
};
constructor(
private formBuilder: FormBuilder,
) { }
ngOnInit() {
this.form = this.formBuilder.group(this.user);
}
}
Upvotes: 1
Reputation: 383
@Input
property will trigger ngOnChanges function only when the Input object is mutated.
In your example, input fields are mutating each single property in the same user object, the user object for the @Input
always refers to the same object (even though its child property name, surename and age are mutated), so ngOnChanges
will not be triggered.
Therefore, you have to make this.user
in component.ts
equals to a brand new user object whenever any input field is changed.
Hope it helps!
Upvotes: 2