I’m a js novice learning angular2 and would be very grateful for any guidance on the following…
Adding to a FormArray via input field
To add values, via a form input, to an existing array I can use (click)=“addAddress()” in the html where addAddress is defined in the component.ts to update values in an array in the form AppComponent:
ngOnInit() {
this.myForm = this._fb.group({
name: ['', [Validators.required, Validators.minLength(5)]],
addresses: this._fb.array([
this.initAddress(),
])
});
}
initAddress() {
return this._fb.group({
street: ['', Validators.required],
postcode: ['']
});
}
addAddress() {
const control = <FormArray>this.myForm.controls['addresses'];
control.push(this.initAddress());
}
And back in the html ngFor is used to add a set of input fields each time the ‘add’ button is clicked":
<div formArrayName="addresses">
<div *ngFor="let address of myForm.controls.addresses.controls; let i=index" >
<span>Address {{i + 1}}</span>
<div [formGroupName]="i">
<input type="text" formControlName="street">
<input type="text" formControlName="postcode">
</div>
</div>
</div>
The full working example here: https://embed.plnkr.co/sUjE1ULYhfDHLNBw2sRv/
Adding to form FormGroup via input field
I would like to understand how to add a completely new FormGroup via form input.
So taking the case of the example above…
Rather than adding to an array of addresses:
{
"name": "",
"addresses": [
{
"street": "Baker Street",
"postcode": "w2"
},
{
"street": "Bond Street",
"postcode": "w1"
}
]
}
Each time an address is added a new FormGroup is created where the user adds the FormGroupName for each via form input:
{
"name":"",
"home":{
"street":"Baker Street",
"postcode":"w2"
},
"work":{
"street":"Bond Street",
"postcode":"w1"
}
}
I have begun to adapt the original example and added a few questions where I’m unsure (which unfortunately turns out to be in a lot of places) but any pointers or direction would be gratefully received even just examples or the concepts to look at that will help me solve the problem! Thanks.
App.Component.ts
constructor(private _fb: FormBuilder) { }
ngOnInit() {
this.myForm = this._fb.group({
name: ['', [Validators.required, Validators.minLength(5)]],
// Each new adress to be added here
//e.g.
/*
home: this._fb.group({
street: ['', Validators.required],
postcode: ['']
});
*/
// Can this be done using this.initiAddress() here
// like in the original example?
});
}
// FormGroupName of the new FomGroup is defined by the 'address' submitted
// Hence added newAddressObj as an argument
initAddress(newAddressObj) {
// but how do I update the function to
// return a named _fb.group to include newAddressObj?
return newAddressObj this._fb.group({
street: ['', Validators.required],
postcode: ['']
});
}
// Added 'address' as an argument.
// 'address' being submitted via form input field
addAddress(address:string) {
// The original example pushes to an existing FormArray:
// <FormArray>this.myForm.controls['addresses']
// How can I add a new FormGroup this._fb.group directly?
//Can I use form.controls.push to do this?:
const control = <FormGroup>this.myForm.controls;
control.push(this.initAddress(address));
}
// Will I need to add a new interface
// each time a new FormGroup is added?
save(model: Customer) {
// call API to save
// ...
console.log(model);
}
}
App.Component.html
<!-- Here want to add a new FormGroup directly to form controls but how? -->
<div *ngFor="let address of myForm.controls" >
<!-- The new formGroupName 'address' is submitted by the user. -->
<!-- What do we use to replace address.value -->
<!-- to access each new 'address' object name added by the user? -->
<div formGroupName="address.value">
<!-- Here want to reference the name of the new address object to display-->
<span> {{ address.value }} </span>
<div >
<label>street</label>
<input type="text" formControlName="street"
[formControl]="address.value.controls.street">
<label>postcode</label>
<input type="text" formControlName="postcode"
[formControl]="address.value.controls.postcode">
</div>
</div>
</div>
<!-- The FormGroupName 'address' is now defined via form input; -->
<input #address (keyup.enter)="addAddress(address.value)"
(blur)="addAddress(address.value); address.value=''" >
<!-- The FormGroupName 'address' is added as an argument -->
<button (click)="addAddress(address.value)">Add new Address</button>