I am trying to use angular 2 model driven forms in my application, but if I have nested objects(with null value) I am not able to make it work as desired.
Here is my code:
person.model.ts (This is Person model object with address as nested object)
import {Address} from './address.model';
export class Person{
personId: string;
name: string
age: number;
address: Address;
}
address.model.ts
export class Address{
addressId: string;
street: string
city: string;
state: string;
zip: string
}
person.component.ts
@Component( {
selector: 'app-person',
templateUrl: 'person.component.html'
})
export class PersonComponent implements OnInit {
personForm: FormGroup;
person: Person;
constructor( private someService: PersonService, private formBuilder: FormBuilder) {}
ngOnInit(){
this.someService.getPersonCall( personId)
.subscribe ( person => {
this.person = person;
this.buildForm();
}
};
buildForm(): void {
this.personForm = this.formBuilder.group ({
'name': [this.person.name, [Validator.required]],
'age': [this.person.age],
'street': [this.person.address.streetOne],
'city': [this.person.address.streetOne],
'state': [this.person.address.state],
'zip': [this.person.address.zip],
});
this.registerForChanges();
}
registerForChanges(): void {
this.personForm.get('name').valueChanges.subscribe(value => this.person.name=value);
this.personForm.get('age').valueChanges.subscribe(value => this.person.age=value);
this.personForm.get('street').valueChanges.subscribe(value => this.person.address.streetOne=value);
this.personForm.get('city').valueChanges.subscribe(value => this.person.address.city=value);
this.personForm.get('state').valueChanges.subscribe(value => this.person.address.state=value);
this.personForm.get('zip').valueChanges.subscribe(value => this.person.address.zip=value);
}
onSubmit() {
this.someService.update(this.person).subscribe( response =>
this.person = response);
}
Here is my person.component.html
<form *ngIf="person" (ngSubmit)="onSubmit()" [formGroup]="personForm"
novalidate>
<div class="col-md-6">
<div class="form-group">
<label for="nameId">Name</label>
<input type="text" class="form-control" formControlName="name" id="nameId"/>
</div>
<div class="form-group">
<label for="ageId">Age</label>
<input type="number" class="form-control" formControlName="age" id="ageId"/>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label for="streetId">Street</label>
<input type="text" class="form-control" formControlName="street" id="streetId"/>
</div>
<div class="form-group">
<label for="cityId">City</label>
<input type="text" class="form-control" formControlName="city" id="cityId"/>
</div>
<div class="form-group">
<label for="stateId">State</label>
<input type="text" class="form-control" formControlName="state" id="stateId"/>
</div>
<div class="form-group">
<label for="zipId">Zip</label>
<input type="text" class="form-control" formControlName="zip" id="zipId"/>
</div>
</div>
<button type="submit" [disabled]="!personForm.valid">Save </button>
</form>
I am trying to update the person object that I populated from the service call, but when I retrieved the person object the person object has the null value on the address property and it is breaking my code in buildForm function.
I tried couple of other ways, but not able to make it work
Version #2
buildForm(): void {
if ( !this.person.address ) {
this.personForm = this.formBuilder.group ({
'name': [this.person.name, [Validator.required]],
'age': [this.person.age],
'street': [''],
'city': [''],
'state': [''],
'zip': [''],
});
} else {
this.personForm = this.formBuilder.group ({
'name': [this.person.name, [Validator.required]],
'age': [this.person.age],
'street': [this.person.address.streetOne],
'city': [this.person.address.streetOne],
'state': [this.person.address.state],
'zip': [this.person.address.zip],
});
}
this.registerForChanges();
}
With this change I was able to render the form without any error, but when I try to update any address fields it failed in registerForChanges function.
Version #3
registerForChanges(): void {
if (! person.address) {
person.address = new Address();
this.personForm.get('name').valueChanges.subscribe(value => this.person.name=value);
this.personForm.get('age').valueChanges.subscribe(value => this.person.age=value);
this.personForm.get('street').valueChanges.subscribe(value => this.person.address.streetOne=value);
this.personForm.get('city').valueChanges.subscribe(value => this.person.address.city=value);
this.personForm.get('state').valueChanges.subscribe(value => this.person.address.state=value);
this.personForm.get('zip').valueChanges.subscribe(value => this.person.address.zip=value);
}
after this change I end up adding empty records to the address table when I save the form without changing the address fields.
This code is working without fine if the address property on the function is not null.
Can someone help me make this code work