Angular 7 : Need help understanding issues I face when building a form with multilevel nested field groups
As you can see on the attached image below, I've built a form in Angular 7. Form contains multiple levels of nested field groups. When pressing "Add Track" button, outer field group is pushed to the dom. Then inside you can press on "+" to add fields inside of each of the outer field groups.
Problem 1:
I keep on receiving the following error and "Add Track" only pushes complete field group into index 1, passed that it is missing fields with "+" buttons that are populated by the nested *ngFor loops in HTML.
Error:
ERROR Error: Cannot find control with path: 'albumTracks -> 1 -> audioSources -> 1'
at _throwError (forms.js:1775)
at setUpFormContainer (forms.js:1757)
at FormGroupDirective.push../node_modules/@angular/forms/fesm5/forms.js.FormGroupDirective.addFormGroup (forms.js:4541)
at FormGroupName.push../node_modules/@angular/forms/fesm5/forms.js.AbstractFormGroupDirective.ngOnInit (forms.js:1887)
at checkAndUpdateDirectiveInline (core.js:9243)
at checkAndUpdateNodeInline (core.js:10507)
at checkAndUpdateNode (core.js:10469)
at debugCheckAndUpdateNode (core.js:11102)
at debugCheckDirectivesFn (core.js:11062)
at Object.eval [as updateDirectives] (AddAlbumsDinamicComponent.html:103)
Problem 2:
When I fill out form and click "Save" button that then executes onSubmit() method and gets all entered form values by: "this.albumForm.value", I am missing bunch of values that I have entered into fields, which were pushed dynamically by pressing "Add Track" and "+" buttons.
Tried to find answers online, but could not find anything similar to what I am trying to do. All online examples are for simple forms, not for multilevel nested form groups. Also new to Angular, need help. S.O.S, thank you so much for your help.
component.ts
import Component, OnInit from '@angular/core';
import FormBuilder, FormGroup, FormArray from '@angular/forms';
import PostRequestService from '../post-request.service';
@Component(
selector: 'app-add-albums-dinamic',
templateUrl: './add-albums-dinamic.component.html',
styleUrls: ['./add-albums-dinamic.component.css']
)
export class AddAlbumsDinamicComponent implements OnInit
albumForm: FormGroup;
items: FormArray;
arrayElement: FormArray;
submitted = false;
constructor(private formBuilder: FormBuilder, private postRequestService: PostRequestService)
ngOnInit()
this.albumForm = this.formBuilder.group(
albumTitle: '',
albumCoverImage: '',
datePublished: '',
albumPurchaseSources: this.formBuilder.array([ this.createAlbumPurchaseSource() ]),
albumTracks: this.formBuilder.array([ this.albumTracksDetails() ])
);
createAlbumPurchaseSource(): FormGroup
return this.formBuilder.group(
albumPurchaseSourceName: '',
albumPurchaseURL: ''
);
createAudioSource(): FormGroup
return this.formBuilder.group(
audioSourceName: '',
audioSourceURL: ''
);
createVideoSource(): FormGroup
return this.formBuilder.group(
videoSourceName: '',
videoSourceURL: ''
);
createTrackPurchaseSource(): FormGroup
return this.formBuilder.group(
trackPurchaseSourceName: '',
trackPurchaseSourceURL: ''
);
albumTracksDetails(): FormGroup
return this.formBuilder.group(
trackTitle: '',
trackGenre: '',
audioSources: this.formBuilder.array([ this.createAudioSource() ]),
videoSources: this.formBuilder.array([ this.createVideoSource() ]),
trackPurchaseSources: this.formBuilder.array([ this.createTrackPurchaseSource() ]),
downloadURL: ''
);
addAudioSource(i: number): void
const control = (<FormArray>this.albumForm.controls['albumTracks']).at(i).get('audioSources') as FormArray;
control.push(this.createAudioSource());
addVideoSource(i: number): void
const control = (<FormArray>this.albumForm.controls['albumTracks']).at(i).get('videoSources') as FormArray;
control.push(this.createVideoSource());
addTrackPurchaseSource(i: number): void
const control = (<FormArray>this.albumForm.controls['albumTracks']).at(i).get('trackPurchaseSources') as FormArray;
control.push(this.createTrackPurchaseSource());
addTracks(): void
this.items = this.albumForm.get('albumTracks') as FormArray;
this.items.push(this.albumTracksDetails());
addAlbumPurchaseSources(): void
this.items = this.albumForm.get('albumPurchaseSources') as FormArray;
this.items.push(this.createAlbumPurchaseSource());
onSubmit()
this.submitted = true;
this.postRequestService.
postRequest(this.albumForm.value)
.subscribe(
(val) =>
console.log("POST call successful value returned in body",
val);
,
response =>
console.log("POST call in error", response);
,
() =>
console.log("The POST observable is now completed.");
);
component.html
<div class="container">
<div id="outer-container">
<div id="sidebar">
<div class="mycontent-left">
<app-artist-admin-sidebar></app-artist-admin-sidebar>
</div>
</div>
<div id="content">
<form [formGroup]="albumForm" (ngSubmit)="onSubmit()" novalidate>
<div><font size="4">Album Details:</font></div>
<br/>
<div class="row">
<div class="col">
<div class="col-sm-2 control-label"><font size="3">Album Title:</font></div>
<div class="col-sm-3 nopadding">
<input type="text" class="form-control" id="album_title" name="album_title" formControlName="albumTitle"
placeholder="Album Title">
</div>
</div>
</div>
<br/>
<div class="row">
<div class="col">
<div class="col-sm-3 control-label"><font size="3">Album Cover Image:</font></div>
<div class="col-sm-3 nopadding">
<input type="file" class="form-control" id="cover_image" name="cover_image"
formControlName="albumCoverImage" placeholder="Album Cover Image">
</div>
</div>
</div>
<br/>
<div class="row">
<div class="col">
<div class="col-sm-3 control-label"><font size="3">Date Published:</font></div>
<div class="col-sm-3 nopadding">
<input type="date" class="form-control" id="date_published" name="date_published"
formControlName="datePublished" placeholder="Date Published">
</div>
</div>
</div>
<br/>
<div formArrayName="albumPurchaseSources"
*ngFor="let item of albumForm.get('albumPurchaseSources').controls; let i = index;">
<div [formGroupName]="i">
<div class="row">
<div class="col">
<div class="col-sm-2 control-label"><font size="3">Album Purchase Source:</font></div>
<div class="col-sm-3 nopadding">
<input type="text" class="form-control" id="album_purchase_source_name"
name="album_purchase_source_name" formControlName="albumPurchaseSourceName"
placeholder="Source Name">
</div>
<div class="col-sm-3 nopadding">
<div class="form-group">
<div class="input-group">
<input type="text" class="form-control" id="album_purchase_url" name="album_purchase_url"
formControlName="albumPurchaseURL" placeholder="URL">
<div class="input-group-btn">
<button class="btn btn-success" type="button" (click)="addAlbumPurchaseSources();"><span
class="glyphicon glyphicon-plus" aria-hidden="true"></span></button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<hr/>
<br/>
<div><font size="4">Album Tracks Details:</font></div>
<br/>
<div formArrayName="albumTracks" *ngFor="let item of albumForm.get('albumTracks').controls; let i = index;">
<div [formGroupName]="i">
<div class="row">
<div class="col">
<div class="col-sm-2 control-label"><font size="3">Track Title:</font></div>
<div class="col-sm-3 nopadding">
<input type="text" class="form-control" id="track_title" name="track_title"
formControlName="trackTitle" placeholder="Track Title">
</div>
</div>
</div>
<br/>
<div class="row">
<div class="col">
<div class="col-sm-2 control-label"><font size="3">Track Genre:</font></div>
<div class="col-sm-3 nopadding">
<input type="text" class="form-control" id="genre" name="genre" formControlName="trackGenre"
placeholder="Genre">
</div>
</div>
</div>
<br/>
<div formArrayName="audioSources" *ngFor="let audioItem of item.controls['audioSources'].controls; let audioi=index;">
<div [formGroupName]="i">
<div class="row">
<div class="col">
<div class="col-sm-2 control-label"><font size="3">Audio:</font></div>
<div class="col-sm-3 nopadding">
<input type="text" class="form-control" id="audio_source_name" name="audio_source_name" formControlName="audioSourceName" placeholder="Audio Source Name">
</div>
<div class="col-sm-3 nopadding">
<div class="form-group">
<div class="input-group">
<input type="text" class="form-control" id="audio_url" name="audio_url" formControlName="audioSourceURL" placeholder="Audio Source URL">
<div class="input-group-btn">
<button class="btn btn-success" type="button" (click)="addAudioSource(i);"><span
class="glyphicon glyphicon-plus" aria-hidden="true"></span></button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<br/>
<div formArrayName="videoSources" *ngFor="let videoItem of item.controls['videoSources'].controls; let videoi = index;">
<div [formGroupName]="i">
<div class="row">
<div class="col">
<div class="col-sm-2 control-label"><font size="3">Video:</font></div>
<div class="col-sm-3 nopadding">
<input type="text" class="form-control" id="video_source_name" name="video_source_name" formControlName="videoSourceName" placeholder="Video Source Name">
</div>
<div class="col-sm-3 nopadding">
<div class="form-group">
<div class="input-group">
<input type="text" class="form-control" id="video_url" name="video_url" formControlName="videoSourceURL" placeholder="Video Source URL">
<div class="input-group-btn">
<button class="btn btn-success" type="button" (click)="addVideoSource(i);"><span
class="glyphicon glyphicon-plus" aria-hidden="true"></span></button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<br/>
<div formArrayName="trackPurchaseSources" *ngFor="let trackPurchaseItem of item.controls['trackPurchaseSources'].controls; let purchasei = index;">
<div [formGroupName]="i">
<div class="row">
<div class="col">
<div class="col-sm-2 control-label"><font size="3">Track Purchase Source:</font></div>
<div class="col-sm-3 nopadding">
<input type="text" class="form-control" id="purchase_source_name" name="purchase_source_name" formControlName="trackPurchaseSourceName" placeholder="Purchase Source Name">
</div>
<div class="col-sm-3 nopadding">
<div class="form-group">
<div class="input-group">
<input type="text" class="form-control" id="purchase_url" name="purchase_url" formControlName="trackPurchaseSourceURL" placeholder="Purchase Source URL">
<div class="input-group-btn">
<button class="btn btn-success" type="button" (click)="addTrackPurchaseSource(i);"><span
class="glyphicon glyphicon-plus" aria-hidden="true"></span></button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<br/>
<div class="row">
<div class="col">
<div class="col-sm-2 control-label"><font size="3">Download:</font></div>
<div class="col-sm-3 nopadding">
<input type="text" class="form-control" id="download_url" name="download_url"
formControlName="downloadURL" placeholder="Download URL">
</div>
</div>
</div>
<br/><hr><br/>
</div>
</div>
<div class="form-group">
<button class="btn btn-success" type="button" (click)="addTracks();">Add Track</button>
</div>
<div class="form-group">
<button class="btn btn-primary">Save</button>
</div>
</form>
</div>
</div>
</div>
angular angular7 angular-ngfor
add a comment |
As you can see on the attached image below, I've built a form in Angular 7. Form contains multiple levels of nested field groups. When pressing "Add Track" button, outer field group is pushed to the dom. Then inside you can press on "+" to add fields inside of each of the outer field groups.
Problem 1:
I keep on receiving the following error and "Add Track" only pushes complete field group into index 1, passed that it is missing fields with "+" buttons that are populated by the nested *ngFor loops in HTML.
Error:
ERROR Error: Cannot find control with path: 'albumTracks -> 1 -> audioSources -> 1'
at _throwError (forms.js:1775)
at setUpFormContainer (forms.js:1757)
at FormGroupDirective.push../node_modules/@angular/forms/fesm5/forms.js.FormGroupDirective.addFormGroup (forms.js:4541)
at FormGroupName.push../node_modules/@angular/forms/fesm5/forms.js.AbstractFormGroupDirective.ngOnInit (forms.js:1887)
at checkAndUpdateDirectiveInline (core.js:9243)
at checkAndUpdateNodeInline (core.js:10507)
at checkAndUpdateNode (core.js:10469)
at debugCheckAndUpdateNode (core.js:11102)
at debugCheckDirectivesFn (core.js:11062)
at Object.eval [as updateDirectives] (AddAlbumsDinamicComponent.html:103)
Problem 2:
When I fill out form and click "Save" button that then executes onSubmit() method and gets all entered form values by: "this.albumForm.value", I am missing bunch of values that I have entered into fields, which were pushed dynamically by pressing "Add Track" and "+" buttons.
Tried to find answers online, but could not find anything similar to what I am trying to do. All online examples are for simple forms, not for multilevel nested form groups. Also new to Angular, need help. S.O.S, thank you so much for your help.
component.ts
import Component, OnInit from '@angular/core';
import FormBuilder, FormGroup, FormArray from '@angular/forms';
import PostRequestService from '../post-request.service';
@Component(
selector: 'app-add-albums-dinamic',
templateUrl: './add-albums-dinamic.component.html',
styleUrls: ['./add-albums-dinamic.component.css']
)
export class AddAlbumsDinamicComponent implements OnInit
albumForm: FormGroup;
items: FormArray;
arrayElement: FormArray;
submitted = false;
constructor(private formBuilder: FormBuilder, private postRequestService: PostRequestService)
ngOnInit()
this.albumForm = this.formBuilder.group(
albumTitle: '',
albumCoverImage: '',
datePublished: '',
albumPurchaseSources: this.formBuilder.array([ this.createAlbumPurchaseSource() ]),
albumTracks: this.formBuilder.array([ this.albumTracksDetails() ])
);
createAlbumPurchaseSource(): FormGroup
return this.formBuilder.group(
albumPurchaseSourceName: '',
albumPurchaseURL: ''
);
createAudioSource(): FormGroup
return this.formBuilder.group(
audioSourceName: '',
audioSourceURL: ''
);
createVideoSource(): FormGroup
return this.formBuilder.group(
videoSourceName: '',
videoSourceURL: ''
);
createTrackPurchaseSource(): FormGroup
return this.formBuilder.group(
trackPurchaseSourceName: '',
trackPurchaseSourceURL: ''
);
albumTracksDetails(): FormGroup
return this.formBuilder.group(
trackTitle: '',
trackGenre: '',
audioSources: this.formBuilder.array([ this.createAudioSource() ]),
videoSources: this.formBuilder.array([ this.createVideoSource() ]),
trackPurchaseSources: this.formBuilder.array([ this.createTrackPurchaseSource() ]),
downloadURL: ''
);
addAudioSource(i: number): void
const control = (<FormArray>this.albumForm.controls['albumTracks']).at(i).get('audioSources') as FormArray;
control.push(this.createAudioSource());
addVideoSource(i: number): void
const control = (<FormArray>this.albumForm.controls['albumTracks']).at(i).get('videoSources') as FormArray;
control.push(this.createVideoSource());
addTrackPurchaseSource(i: number): void
const control = (<FormArray>this.albumForm.controls['albumTracks']).at(i).get('trackPurchaseSources') as FormArray;
control.push(this.createTrackPurchaseSource());
addTracks(): void
this.items = this.albumForm.get('albumTracks') as FormArray;
this.items.push(this.albumTracksDetails());
addAlbumPurchaseSources(): void
this.items = this.albumForm.get('albumPurchaseSources') as FormArray;
this.items.push(this.createAlbumPurchaseSource());
onSubmit()
this.submitted = true;
this.postRequestService.
postRequest(this.albumForm.value)
.subscribe(
(val) =>
console.log("POST call successful value returned in body",
val);
,
response =>
console.log("POST call in error", response);
,
() =>
console.log("The POST observable is now completed.");
);
component.html
<div class="container">
<div id="outer-container">
<div id="sidebar">
<div class="mycontent-left">
<app-artist-admin-sidebar></app-artist-admin-sidebar>
</div>
</div>
<div id="content">
<form [formGroup]="albumForm" (ngSubmit)="onSubmit()" novalidate>
<div><font size="4">Album Details:</font></div>
<br/>
<div class="row">
<div class="col">
<div class="col-sm-2 control-label"><font size="3">Album Title:</font></div>
<div class="col-sm-3 nopadding">
<input type="text" class="form-control" id="album_title" name="album_title" formControlName="albumTitle"
placeholder="Album Title">
</div>
</div>
</div>
<br/>
<div class="row">
<div class="col">
<div class="col-sm-3 control-label"><font size="3">Album Cover Image:</font></div>
<div class="col-sm-3 nopadding">
<input type="file" class="form-control" id="cover_image" name="cover_image"
formControlName="albumCoverImage" placeholder="Album Cover Image">
</div>
</div>
</div>
<br/>
<div class="row">
<div class="col">
<div class="col-sm-3 control-label"><font size="3">Date Published:</font></div>
<div class="col-sm-3 nopadding">
<input type="date" class="form-control" id="date_published" name="date_published"
formControlName="datePublished" placeholder="Date Published">
</div>
</div>
</div>
<br/>
<div formArrayName="albumPurchaseSources"
*ngFor="let item of albumForm.get('albumPurchaseSources').controls; let i = index;">
<div [formGroupName]="i">
<div class="row">
<div class="col">
<div class="col-sm-2 control-label"><font size="3">Album Purchase Source:</font></div>
<div class="col-sm-3 nopadding">
<input type="text" class="form-control" id="album_purchase_source_name"
name="album_purchase_source_name" formControlName="albumPurchaseSourceName"
placeholder="Source Name">
</div>
<div class="col-sm-3 nopadding">
<div class="form-group">
<div class="input-group">
<input type="text" class="form-control" id="album_purchase_url" name="album_purchase_url"
formControlName="albumPurchaseURL" placeholder="URL">
<div class="input-group-btn">
<button class="btn btn-success" type="button" (click)="addAlbumPurchaseSources();"><span
class="glyphicon glyphicon-plus" aria-hidden="true"></span></button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<hr/>
<br/>
<div><font size="4">Album Tracks Details:</font></div>
<br/>
<div formArrayName="albumTracks" *ngFor="let item of albumForm.get('albumTracks').controls; let i = index;">
<div [formGroupName]="i">
<div class="row">
<div class="col">
<div class="col-sm-2 control-label"><font size="3">Track Title:</font></div>
<div class="col-sm-3 nopadding">
<input type="text" class="form-control" id="track_title" name="track_title"
formControlName="trackTitle" placeholder="Track Title">
</div>
</div>
</div>
<br/>
<div class="row">
<div class="col">
<div class="col-sm-2 control-label"><font size="3">Track Genre:</font></div>
<div class="col-sm-3 nopadding">
<input type="text" class="form-control" id="genre" name="genre" formControlName="trackGenre"
placeholder="Genre">
</div>
</div>
</div>
<br/>
<div formArrayName="audioSources" *ngFor="let audioItem of item.controls['audioSources'].controls; let audioi=index;">
<div [formGroupName]="i">
<div class="row">
<div class="col">
<div class="col-sm-2 control-label"><font size="3">Audio:</font></div>
<div class="col-sm-3 nopadding">
<input type="text" class="form-control" id="audio_source_name" name="audio_source_name" formControlName="audioSourceName" placeholder="Audio Source Name">
</div>
<div class="col-sm-3 nopadding">
<div class="form-group">
<div class="input-group">
<input type="text" class="form-control" id="audio_url" name="audio_url" formControlName="audioSourceURL" placeholder="Audio Source URL">
<div class="input-group-btn">
<button class="btn btn-success" type="button" (click)="addAudioSource(i);"><span
class="glyphicon glyphicon-plus" aria-hidden="true"></span></button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<br/>
<div formArrayName="videoSources" *ngFor="let videoItem of item.controls['videoSources'].controls; let videoi = index;">
<div [formGroupName]="i">
<div class="row">
<div class="col">
<div class="col-sm-2 control-label"><font size="3">Video:</font></div>
<div class="col-sm-3 nopadding">
<input type="text" class="form-control" id="video_source_name" name="video_source_name" formControlName="videoSourceName" placeholder="Video Source Name">
</div>
<div class="col-sm-3 nopadding">
<div class="form-group">
<div class="input-group">
<input type="text" class="form-control" id="video_url" name="video_url" formControlName="videoSourceURL" placeholder="Video Source URL">
<div class="input-group-btn">
<button class="btn btn-success" type="button" (click)="addVideoSource(i);"><span
class="glyphicon glyphicon-plus" aria-hidden="true"></span></button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<br/>
<div formArrayName="trackPurchaseSources" *ngFor="let trackPurchaseItem of item.controls['trackPurchaseSources'].controls; let purchasei = index;">
<div [formGroupName]="i">
<div class="row">
<div class="col">
<div class="col-sm-2 control-label"><font size="3">Track Purchase Source:</font></div>
<div class="col-sm-3 nopadding">
<input type="text" class="form-control" id="purchase_source_name" name="purchase_source_name" formControlName="trackPurchaseSourceName" placeholder="Purchase Source Name">
</div>
<div class="col-sm-3 nopadding">
<div class="form-group">
<div class="input-group">
<input type="text" class="form-control" id="purchase_url" name="purchase_url" formControlName="trackPurchaseSourceURL" placeholder="Purchase Source URL">
<div class="input-group-btn">
<button class="btn btn-success" type="button" (click)="addTrackPurchaseSource(i);"><span
class="glyphicon glyphicon-plus" aria-hidden="true"></span></button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<br/>
<div class="row">
<div class="col">
<div class="col-sm-2 control-label"><font size="3">Download:</font></div>
<div class="col-sm-3 nopadding">
<input type="text" class="form-control" id="download_url" name="download_url"
formControlName="downloadURL" placeholder="Download URL">
</div>
</div>
</div>
<br/><hr><br/>
</div>
</div>
<div class="form-group">
<button class="btn btn-success" type="button" (click)="addTracks();">Add Track</button>
</div>
<div class="form-group">
<button class="btn btn-primary">Save</button>
</div>
</form>
</div>
</div>
</div>
angular angular7 angular-ngfor
add a comment |
As you can see on the attached image below, I've built a form in Angular 7. Form contains multiple levels of nested field groups. When pressing "Add Track" button, outer field group is pushed to the dom. Then inside you can press on "+" to add fields inside of each of the outer field groups.
Problem 1:
I keep on receiving the following error and "Add Track" only pushes complete field group into index 1, passed that it is missing fields with "+" buttons that are populated by the nested *ngFor loops in HTML.
Error:
ERROR Error: Cannot find control with path: 'albumTracks -> 1 -> audioSources -> 1'
at _throwError (forms.js:1775)
at setUpFormContainer (forms.js:1757)
at FormGroupDirective.push../node_modules/@angular/forms/fesm5/forms.js.FormGroupDirective.addFormGroup (forms.js:4541)
at FormGroupName.push../node_modules/@angular/forms/fesm5/forms.js.AbstractFormGroupDirective.ngOnInit (forms.js:1887)
at checkAndUpdateDirectiveInline (core.js:9243)
at checkAndUpdateNodeInline (core.js:10507)
at checkAndUpdateNode (core.js:10469)
at debugCheckAndUpdateNode (core.js:11102)
at debugCheckDirectivesFn (core.js:11062)
at Object.eval [as updateDirectives] (AddAlbumsDinamicComponent.html:103)
Problem 2:
When I fill out form and click "Save" button that then executes onSubmit() method and gets all entered form values by: "this.albumForm.value", I am missing bunch of values that I have entered into fields, which were pushed dynamically by pressing "Add Track" and "+" buttons.
Tried to find answers online, but could not find anything similar to what I am trying to do. All online examples are for simple forms, not for multilevel nested form groups. Also new to Angular, need help. S.O.S, thank you so much for your help.
component.ts
import Component, OnInit from '@angular/core';
import FormBuilder, FormGroup, FormArray from '@angular/forms';
import PostRequestService from '../post-request.service';
@Component(
selector: 'app-add-albums-dinamic',
templateUrl: './add-albums-dinamic.component.html',
styleUrls: ['./add-albums-dinamic.component.css']
)
export class AddAlbumsDinamicComponent implements OnInit
albumForm: FormGroup;
items: FormArray;
arrayElement: FormArray;
submitted = false;
constructor(private formBuilder: FormBuilder, private postRequestService: PostRequestService)
ngOnInit()
this.albumForm = this.formBuilder.group(
albumTitle: '',
albumCoverImage: '',
datePublished: '',
albumPurchaseSources: this.formBuilder.array([ this.createAlbumPurchaseSource() ]),
albumTracks: this.formBuilder.array([ this.albumTracksDetails() ])
);
createAlbumPurchaseSource(): FormGroup
return this.formBuilder.group(
albumPurchaseSourceName: '',
albumPurchaseURL: ''
);
createAudioSource(): FormGroup
return this.formBuilder.group(
audioSourceName: '',
audioSourceURL: ''
);
createVideoSource(): FormGroup
return this.formBuilder.group(
videoSourceName: '',
videoSourceURL: ''
);
createTrackPurchaseSource(): FormGroup
return this.formBuilder.group(
trackPurchaseSourceName: '',
trackPurchaseSourceURL: ''
);
albumTracksDetails(): FormGroup
return this.formBuilder.group(
trackTitle: '',
trackGenre: '',
audioSources: this.formBuilder.array([ this.createAudioSource() ]),
videoSources: this.formBuilder.array([ this.createVideoSource() ]),
trackPurchaseSources: this.formBuilder.array([ this.createTrackPurchaseSource() ]),
downloadURL: ''
);
addAudioSource(i: number): void
const control = (<FormArray>this.albumForm.controls['albumTracks']).at(i).get('audioSources') as FormArray;
control.push(this.createAudioSource());
addVideoSource(i: number): void
const control = (<FormArray>this.albumForm.controls['albumTracks']).at(i).get('videoSources') as FormArray;
control.push(this.createVideoSource());
addTrackPurchaseSource(i: number): void
const control = (<FormArray>this.albumForm.controls['albumTracks']).at(i).get('trackPurchaseSources') as FormArray;
control.push(this.createTrackPurchaseSource());
addTracks(): void
this.items = this.albumForm.get('albumTracks') as FormArray;
this.items.push(this.albumTracksDetails());
addAlbumPurchaseSources(): void
this.items = this.albumForm.get('albumPurchaseSources') as FormArray;
this.items.push(this.createAlbumPurchaseSource());
onSubmit()
this.submitted = true;
this.postRequestService.
postRequest(this.albumForm.value)
.subscribe(
(val) =>
console.log("POST call successful value returned in body",
val);
,
response =>
console.log("POST call in error", response);
,
() =>
console.log("The POST observable is now completed.");
);
component.html
<div class="container">
<div id="outer-container">
<div id="sidebar">
<div class="mycontent-left">
<app-artist-admin-sidebar></app-artist-admin-sidebar>
</div>
</div>
<div id="content">
<form [formGroup]="albumForm" (ngSubmit)="onSubmit()" novalidate>
<div><font size="4">Album Details:</font></div>
<br/>
<div class="row">
<div class="col">
<div class="col-sm-2 control-label"><font size="3">Album Title:</font></div>
<div class="col-sm-3 nopadding">
<input type="text" class="form-control" id="album_title" name="album_title" formControlName="albumTitle"
placeholder="Album Title">
</div>
</div>
</div>
<br/>
<div class="row">
<div class="col">
<div class="col-sm-3 control-label"><font size="3">Album Cover Image:</font></div>
<div class="col-sm-3 nopadding">
<input type="file" class="form-control" id="cover_image" name="cover_image"
formControlName="albumCoverImage" placeholder="Album Cover Image">
</div>
</div>
</div>
<br/>
<div class="row">
<div class="col">
<div class="col-sm-3 control-label"><font size="3">Date Published:</font></div>
<div class="col-sm-3 nopadding">
<input type="date" class="form-control" id="date_published" name="date_published"
formControlName="datePublished" placeholder="Date Published">
</div>
</div>
</div>
<br/>
<div formArrayName="albumPurchaseSources"
*ngFor="let item of albumForm.get('albumPurchaseSources').controls; let i = index;">
<div [formGroupName]="i">
<div class="row">
<div class="col">
<div class="col-sm-2 control-label"><font size="3">Album Purchase Source:</font></div>
<div class="col-sm-3 nopadding">
<input type="text" class="form-control" id="album_purchase_source_name"
name="album_purchase_source_name" formControlName="albumPurchaseSourceName"
placeholder="Source Name">
</div>
<div class="col-sm-3 nopadding">
<div class="form-group">
<div class="input-group">
<input type="text" class="form-control" id="album_purchase_url" name="album_purchase_url"
formControlName="albumPurchaseURL" placeholder="URL">
<div class="input-group-btn">
<button class="btn btn-success" type="button" (click)="addAlbumPurchaseSources();"><span
class="glyphicon glyphicon-plus" aria-hidden="true"></span></button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<hr/>
<br/>
<div><font size="4">Album Tracks Details:</font></div>
<br/>
<div formArrayName="albumTracks" *ngFor="let item of albumForm.get('albumTracks').controls; let i = index;">
<div [formGroupName]="i">
<div class="row">
<div class="col">
<div class="col-sm-2 control-label"><font size="3">Track Title:</font></div>
<div class="col-sm-3 nopadding">
<input type="text" class="form-control" id="track_title" name="track_title"
formControlName="trackTitle" placeholder="Track Title">
</div>
</div>
</div>
<br/>
<div class="row">
<div class="col">
<div class="col-sm-2 control-label"><font size="3">Track Genre:</font></div>
<div class="col-sm-3 nopadding">
<input type="text" class="form-control" id="genre" name="genre" formControlName="trackGenre"
placeholder="Genre">
</div>
</div>
</div>
<br/>
<div formArrayName="audioSources" *ngFor="let audioItem of item.controls['audioSources'].controls; let audioi=index;">
<div [formGroupName]="i">
<div class="row">
<div class="col">
<div class="col-sm-2 control-label"><font size="3">Audio:</font></div>
<div class="col-sm-3 nopadding">
<input type="text" class="form-control" id="audio_source_name" name="audio_source_name" formControlName="audioSourceName" placeholder="Audio Source Name">
</div>
<div class="col-sm-3 nopadding">
<div class="form-group">
<div class="input-group">
<input type="text" class="form-control" id="audio_url" name="audio_url" formControlName="audioSourceURL" placeholder="Audio Source URL">
<div class="input-group-btn">
<button class="btn btn-success" type="button" (click)="addAudioSource(i);"><span
class="glyphicon glyphicon-plus" aria-hidden="true"></span></button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<br/>
<div formArrayName="videoSources" *ngFor="let videoItem of item.controls['videoSources'].controls; let videoi = index;">
<div [formGroupName]="i">
<div class="row">
<div class="col">
<div class="col-sm-2 control-label"><font size="3">Video:</font></div>
<div class="col-sm-3 nopadding">
<input type="text" class="form-control" id="video_source_name" name="video_source_name" formControlName="videoSourceName" placeholder="Video Source Name">
</div>
<div class="col-sm-3 nopadding">
<div class="form-group">
<div class="input-group">
<input type="text" class="form-control" id="video_url" name="video_url" formControlName="videoSourceURL" placeholder="Video Source URL">
<div class="input-group-btn">
<button class="btn btn-success" type="button" (click)="addVideoSource(i);"><span
class="glyphicon glyphicon-plus" aria-hidden="true"></span></button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<br/>
<div formArrayName="trackPurchaseSources" *ngFor="let trackPurchaseItem of item.controls['trackPurchaseSources'].controls; let purchasei = index;">
<div [formGroupName]="i">
<div class="row">
<div class="col">
<div class="col-sm-2 control-label"><font size="3">Track Purchase Source:</font></div>
<div class="col-sm-3 nopadding">
<input type="text" class="form-control" id="purchase_source_name" name="purchase_source_name" formControlName="trackPurchaseSourceName" placeholder="Purchase Source Name">
</div>
<div class="col-sm-3 nopadding">
<div class="form-group">
<div class="input-group">
<input type="text" class="form-control" id="purchase_url" name="purchase_url" formControlName="trackPurchaseSourceURL" placeholder="Purchase Source URL">
<div class="input-group-btn">
<button class="btn btn-success" type="button" (click)="addTrackPurchaseSource(i);"><span
class="glyphicon glyphicon-plus" aria-hidden="true"></span></button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<br/>
<div class="row">
<div class="col">
<div class="col-sm-2 control-label"><font size="3">Download:</font></div>
<div class="col-sm-3 nopadding">
<input type="text" class="form-control" id="download_url" name="download_url"
formControlName="downloadURL" placeholder="Download URL">
</div>
</div>
</div>
<br/><hr><br/>
</div>
</div>
<div class="form-group">
<button class="btn btn-success" type="button" (click)="addTracks();">Add Track</button>
</div>
<div class="form-group">
<button class="btn btn-primary">Save</button>
</div>
</form>
</div>
</div>
</div>
angular angular7 angular-ngfor
As you can see on the attached image below, I've built a form in Angular 7. Form contains multiple levels of nested field groups. When pressing "Add Track" button, outer field group is pushed to the dom. Then inside you can press on "+" to add fields inside of each of the outer field groups.
Problem 1:
I keep on receiving the following error and "Add Track" only pushes complete field group into index 1, passed that it is missing fields with "+" buttons that are populated by the nested *ngFor loops in HTML.
Error:
ERROR Error: Cannot find control with path: 'albumTracks -> 1 -> audioSources -> 1'
at _throwError (forms.js:1775)
at setUpFormContainer (forms.js:1757)
at FormGroupDirective.push../node_modules/@angular/forms/fesm5/forms.js.FormGroupDirective.addFormGroup (forms.js:4541)
at FormGroupName.push../node_modules/@angular/forms/fesm5/forms.js.AbstractFormGroupDirective.ngOnInit (forms.js:1887)
at checkAndUpdateDirectiveInline (core.js:9243)
at checkAndUpdateNodeInline (core.js:10507)
at checkAndUpdateNode (core.js:10469)
at debugCheckAndUpdateNode (core.js:11102)
at debugCheckDirectivesFn (core.js:11062)
at Object.eval [as updateDirectives] (AddAlbumsDinamicComponent.html:103)
Problem 2:
When I fill out form and click "Save" button that then executes onSubmit() method and gets all entered form values by: "this.albumForm.value", I am missing bunch of values that I have entered into fields, which were pushed dynamically by pressing "Add Track" and "+" buttons.
Tried to find answers online, but could not find anything similar to what I am trying to do. All online examples are for simple forms, not for multilevel nested form groups. Also new to Angular, need help. S.O.S, thank you so much for your help.
component.ts
import Component, OnInit from '@angular/core';
import FormBuilder, FormGroup, FormArray from '@angular/forms';
import PostRequestService from '../post-request.service';
@Component(
selector: 'app-add-albums-dinamic',
templateUrl: './add-albums-dinamic.component.html',
styleUrls: ['./add-albums-dinamic.component.css']
)
export class AddAlbumsDinamicComponent implements OnInit
albumForm: FormGroup;
items: FormArray;
arrayElement: FormArray;
submitted = false;
constructor(private formBuilder: FormBuilder, private postRequestService: PostRequestService)
ngOnInit()
this.albumForm = this.formBuilder.group(
albumTitle: '',
albumCoverImage: '',
datePublished: '',
albumPurchaseSources: this.formBuilder.array([ this.createAlbumPurchaseSource() ]),
albumTracks: this.formBuilder.array([ this.albumTracksDetails() ])
);
createAlbumPurchaseSource(): FormGroup
return this.formBuilder.group(
albumPurchaseSourceName: '',
albumPurchaseURL: ''
);
createAudioSource(): FormGroup
return this.formBuilder.group(
audioSourceName: '',
audioSourceURL: ''
);
createVideoSource(): FormGroup
return this.formBuilder.group(
videoSourceName: '',
videoSourceURL: ''
);
createTrackPurchaseSource(): FormGroup
return this.formBuilder.group(
trackPurchaseSourceName: '',
trackPurchaseSourceURL: ''
);
albumTracksDetails(): FormGroup
return this.formBuilder.group(
trackTitle: '',
trackGenre: '',
audioSources: this.formBuilder.array([ this.createAudioSource() ]),
videoSources: this.formBuilder.array([ this.createVideoSource() ]),
trackPurchaseSources: this.formBuilder.array([ this.createTrackPurchaseSource() ]),
downloadURL: ''
);
addAudioSource(i: number): void
const control = (<FormArray>this.albumForm.controls['albumTracks']).at(i).get('audioSources') as FormArray;
control.push(this.createAudioSource());
addVideoSource(i: number): void
const control = (<FormArray>this.albumForm.controls['albumTracks']).at(i).get('videoSources') as FormArray;
control.push(this.createVideoSource());
addTrackPurchaseSource(i: number): void
const control = (<FormArray>this.albumForm.controls['albumTracks']).at(i).get('trackPurchaseSources') as FormArray;
control.push(this.createTrackPurchaseSource());
addTracks(): void
this.items = this.albumForm.get('albumTracks') as FormArray;
this.items.push(this.albumTracksDetails());
addAlbumPurchaseSources(): void
this.items = this.albumForm.get('albumPurchaseSources') as FormArray;
this.items.push(this.createAlbumPurchaseSource());
onSubmit()
this.submitted = true;
this.postRequestService.
postRequest(this.albumForm.value)
.subscribe(
(val) =>
console.log("POST call successful value returned in body",
val);
,
response =>
console.log("POST call in error", response);
,
() =>
console.log("The POST observable is now completed.");
);
component.html
<div class="container">
<div id="outer-container">
<div id="sidebar">
<div class="mycontent-left">
<app-artist-admin-sidebar></app-artist-admin-sidebar>
</div>
</div>
<div id="content">
<form [formGroup]="albumForm" (ngSubmit)="onSubmit()" novalidate>
<div><font size="4">Album Details:</font></div>
<br/>
<div class="row">
<div class="col">
<div class="col-sm-2 control-label"><font size="3">Album Title:</font></div>
<div class="col-sm-3 nopadding">
<input type="text" class="form-control" id="album_title" name="album_title" formControlName="albumTitle"
placeholder="Album Title">
</div>
</div>
</div>
<br/>
<div class="row">
<div class="col">
<div class="col-sm-3 control-label"><font size="3">Album Cover Image:</font></div>
<div class="col-sm-3 nopadding">
<input type="file" class="form-control" id="cover_image" name="cover_image"
formControlName="albumCoverImage" placeholder="Album Cover Image">
</div>
</div>
</div>
<br/>
<div class="row">
<div class="col">
<div class="col-sm-3 control-label"><font size="3">Date Published:</font></div>
<div class="col-sm-3 nopadding">
<input type="date" class="form-control" id="date_published" name="date_published"
formControlName="datePublished" placeholder="Date Published">
</div>
</div>
</div>
<br/>
<div formArrayName="albumPurchaseSources"
*ngFor="let item of albumForm.get('albumPurchaseSources').controls; let i = index;">
<div [formGroupName]="i">
<div class="row">
<div class="col">
<div class="col-sm-2 control-label"><font size="3">Album Purchase Source:</font></div>
<div class="col-sm-3 nopadding">
<input type="text" class="form-control" id="album_purchase_source_name"
name="album_purchase_source_name" formControlName="albumPurchaseSourceName"
placeholder="Source Name">
</div>
<div class="col-sm-3 nopadding">
<div class="form-group">
<div class="input-group">
<input type="text" class="form-control" id="album_purchase_url" name="album_purchase_url"
formControlName="albumPurchaseURL" placeholder="URL">
<div class="input-group-btn">
<button class="btn btn-success" type="button" (click)="addAlbumPurchaseSources();"><span
class="glyphicon glyphicon-plus" aria-hidden="true"></span></button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<hr/>
<br/>
<div><font size="4">Album Tracks Details:</font></div>
<br/>
<div formArrayName="albumTracks" *ngFor="let item of albumForm.get('albumTracks').controls; let i = index;">
<div [formGroupName]="i">
<div class="row">
<div class="col">
<div class="col-sm-2 control-label"><font size="3">Track Title:</font></div>
<div class="col-sm-3 nopadding">
<input type="text" class="form-control" id="track_title" name="track_title"
formControlName="trackTitle" placeholder="Track Title">
</div>
</div>
</div>
<br/>
<div class="row">
<div class="col">
<div class="col-sm-2 control-label"><font size="3">Track Genre:</font></div>
<div class="col-sm-3 nopadding">
<input type="text" class="form-control" id="genre" name="genre" formControlName="trackGenre"
placeholder="Genre">
</div>
</div>
</div>
<br/>
<div formArrayName="audioSources" *ngFor="let audioItem of item.controls['audioSources'].controls; let audioi=index;">
<div [formGroupName]="i">
<div class="row">
<div class="col">
<div class="col-sm-2 control-label"><font size="3">Audio:</font></div>
<div class="col-sm-3 nopadding">
<input type="text" class="form-control" id="audio_source_name" name="audio_source_name" formControlName="audioSourceName" placeholder="Audio Source Name">
</div>
<div class="col-sm-3 nopadding">
<div class="form-group">
<div class="input-group">
<input type="text" class="form-control" id="audio_url" name="audio_url" formControlName="audioSourceURL" placeholder="Audio Source URL">
<div class="input-group-btn">
<button class="btn btn-success" type="button" (click)="addAudioSource(i);"><span
class="glyphicon glyphicon-plus" aria-hidden="true"></span></button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<br/>
<div formArrayName="videoSources" *ngFor="let videoItem of item.controls['videoSources'].controls; let videoi = index;">
<div [formGroupName]="i">
<div class="row">
<div class="col">
<div class="col-sm-2 control-label"><font size="3">Video:</font></div>
<div class="col-sm-3 nopadding">
<input type="text" class="form-control" id="video_source_name" name="video_source_name" formControlName="videoSourceName" placeholder="Video Source Name">
</div>
<div class="col-sm-3 nopadding">
<div class="form-group">
<div class="input-group">
<input type="text" class="form-control" id="video_url" name="video_url" formControlName="videoSourceURL" placeholder="Video Source URL">
<div class="input-group-btn">
<button class="btn btn-success" type="button" (click)="addVideoSource(i);"><span
class="glyphicon glyphicon-plus" aria-hidden="true"></span></button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<br/>
<div formArrayName="trackPurchaseSources" *ngFor="let trackPurchaseItem of item.controls['trackPurchaseSources'].controls; let purchasei = index;">
<div [formGroupName]="i">
<div class="row">
<div class="col">
<div class="col-sm-2 control-label"><font size="3">Track Purchase Source:</font></div>
<div class="col-sm-3 nopadding">
<input type="text" class="form-control" id="purchase_source_name" name="purchase_source_name" formControlName="trackPurchaseSourceName" placeholder="Purchase Source Name">
</div>
<div class="col-sm-3 nopadding">
<div class="form-group">
<div class="input-group">
<input type="text" class="form-control" id="purchase_url" name="purchase_url" formControlName="trackPurchaseSourceURL" placeholder="Purchase Source URL">
<div class="input-group-btn">
<button class="btn btn-success" type="button" (click)="addTrackPurchaseSource(i);"><span
class="glyphicon glyphicon-plus" aria-hidden="true"></span></button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<br/>
<div class="row">
<div class="col">
<div class="col-sm-2 control-label"><font size="3">Download:</font></div>
<div class="col-sm-3 nopadding">
<input type="text" class="form-control" id="download_url" name="download_url"
formControlName="downloadURL" placeholder="Download URL">
</div>
</div>
</div>
<br/><hr><br/>
</div>
</div>
<div class="form-group">
<button class="btn btn-success" type="button" (click)="addTracks();">Add Track</button>
</div>
<div class="form-group">
<button class="btn btn-primary">Save</button>
</div>
</form>
</div>
</div>
</div>
angular angular7 angular-ngfor
angular angular7 angular-ngfor
edited Nov 11 at 18:29
Goncalo Peres
1,3091317
1,3091317
asked Nov 11 at 5:35
Igor Vishnevskiy
6182613
6182613
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
Works here: https://stackblitz.com/edit/so-53246132
Problem #1:
<div formArrayName="audioSources" *ngFor="let audioItem of item.controls['audioSources'].controls; let audioi=index;">
<div [formGroupName]="i">
But should be:
<div formArrayName="audioSources" *ngFor="let audioItem of item.controls['audioSources'].controls; let audioi=index;">
<div [formGroupName]="audioi">
Same for videoi
and purchasei
.
Problem #2:
addTracks(): void
(this.albumForm.get('albumTracks') as FormArray).push(this.albumTracksDetails());
// why? what is items?
// this.items = this.albumForm.get('albumTracks') as FormArray;
// this.items.push(this.albumTracksDetails());
Also subject to change is:
addAlbumPurchaseSources(): void
this.items = this.albumForm.get('albumPurchaseSources') as FormArray;
this.items.push(this.createAlbumPurchaseSource());
Oh wow. For problem 1, how could I miss those. :) Copy pasting problem, forgot to change i to audioi, videoi and purchasei for index var names. Thank you.
– Igor Vishnevskiy
Nov 11 at 7:12
Thank you. You correction to problem 1 actually fixed all both issues. I see all values return to me when I submit the form now too. Thank you!
– Igor Vishnevskiy
Nov 11 at 7:28
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53246132%2fangular-7-need-help-understanding-issues-i-face-when-building-a-form-with-mult%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Works here: https://stackblitz.com/edit/so-53246132
Problem #1:
<div formArrayName="audioSources" *ngFor="let audioItem of item.controls['audioSources'].controls; let audioi=index;">
<div [formGroupName]="i">
But should be:
<div formArrayName="audioSources" *ngFor="let audioItem of item.controls['audioSources'].controls; let audioi=index;">
<div [formGroupName]="audioi">
Same for videoi
and purchasei
.
Problem #2:
addTracks(): void
(this.albumForm.get('albumTracks') as FormArray).push(this.albumTracksDetails());
// why? what is items?
// this.items = this.albumForm.get('albumTracks') as FormArray;
// this.items.push(this.albumTracksDetails());
Also subject to change is:
addAlbumPurchaseSources(): void
this.items = this.albumForm.get('albumPurchaseSources') as FormArray;
this.items.push(this.createAlbumPurchaseSource());
Oh wow. For problem 1, how could I miss those. :) Copy pasting problem, forgot to change i to audioi, videoi and purchasei for index var names. Thank you.
– Igor Vishnevskiy
Nov 11 at 7:12
Thank you. You correction to problem 1 actually fixed all both issues. I see all values return to me when I submit the form now too. Thank you!
– Igor Vishnevskiy
Nov 11 at 7:28
add a comment |
Works here: https://stackblitz.com/edit/so-53246132
Problem #1:
<div formArrayName="audioSources" *ngFor="let audioItem of item.controls['audioSources'].controls; let audioi=index;">
<div [formGroupName]="i">
But should be:
<div formArrayName="audioSources" *ngFor="let audioItem of item.controls['audioSources'].controls; let audioi=index;">
<div [formGroupName]="audioi">
Same for videoi
and purchasei
.
Problem #2:
addTracks(): void
(this.albumForm.get('albumTracks') as FormArray).push(this.albumTracksDetails());
// why? what is items?
// this.items = this.albumForm.get('albumTracks') as FormArray;
// this.items.push(this.albumTracksDetails());
Also subject to change is:
addAlbumPurchaseSources(): void
this.items = this.albumForm.get('albumPurchaseSources') as FormArray;
this.items.push(this.createAlbumPurchaseSource());
Oh wow. For problem 1, how could I miss those. :) Copy pasting problem, forgot to change i to audioi, videoi and purchasei for index var names. Thank you.
– Igor Vishnevskiy
Nov 11 at 7:12
Thank you. You correction to problem 1 actually fixed all both issues. I see all values return to me when I submit the form now too. Thank you!
– Igor Vishnevskiy
Nov 11 at 7:28
add a comment |
Works here: https://stackblitz.com/edit/so-53246132
Problem #1:
<div formArrayName="audioSources" *ngFor="let audioItem of item.controls['audioSources'].controls; let audioi=index;">
<div [formGroupName]="i">
But should be:
<div formArrayName="audioSources" *ngFor="let audioItem of item.controls['audioSources'].controls; let audioi=index;">
<div [formGroupName]="audioi">
Same for videoi
and purchasei
.
Problem #2:
addTracks(): void
(this.albumForm.get('albumTracks') as FormArray).push(this.albumTracksDetails());
// why? what is items?
// this.items = this.albumForm.get('albumTracks') as FormArray;
// this.items.push(this.albumTracksDetails());
Also subject to change is:
addAlbumPurchaseSources(): void
this.items = this.albumForm.get('albumPurchaseSources') as FormArray;
this.items.push(this.createAlbumPurchaseSource());
Works here: https://stackblitz.com/edit/so-53246132
Problem #1:
<div formArrayName="audioSources" *ngFor="let audioItem of item.controls['audioSources'].controls; let audioi=index;">
<div [formGroupName]="i">
But should be:
<div formArrayName="audioSources" *ngFor="let audioItem of item.controls['audioSources'].controls; let audioi=index;">
<div [formGroupName]="audioi">
Same for videoi
and purchasei
.
Problem #2:
addTracks(): void
(this.albumForm.get('albumTracks') as FormArray).push(this.albumTracksDetails());
// why? what is items?
// this.items = this.albumForm.get('albumTracks') as FormArray;
// this.items.push(this.albumTracksDetails());
Also subject to change is:
addAlbumPurchaseSources(): void
this.items = this.albumForm.get('albumPurchaseSources') as FormArray;
this.items.push(this.createAlbumPurchaseSource());
answered Nov 11 at 6:06
muradm
866519
866519
Oh wow. For problem 1, how could I miss those. :) Copy pasting problem, forgot to change i to audioi, videoi and purchasei for index var names. Thank you.
– Igor Vishnevskiy
Nov 11 at 7:12
Thank you. You correction to problem 1 actually fixed all both issues. I see all values return to me when I submit the form now too. Thank you!
– Igor Vishnevskiy
Nov 11 at 7:28
add a comment |
Oh wow. For problem 1, how could I miss those. :) Copy pasting problem, forgot to change i to audioi, videoi and purchasei for index var names. Thank you.
– Igor Vishnevskiy
Nov 11 at 7:12
Thank you. You correction to problem 1 actually fixed all both issues. I see all values return to me when I submit the form now too. Thank you!
– Igor Vishnevskiy
Nov 11 at 7:28
Oh wow. For problem 1, how could I miss those. :) Copy pasting problem, forgot to change i to audioi, videoi and purchasei for index var names. Thank you.
– Igor Vishnevskiy
Nov 11 at 7:12
Oh wow. For problem 1, how could I miss those. :) Copy pasting problem, forgot to change i to audioi, videoi and purchasei for index var names. Thank you.
– Igor Vishnevskiy
Nov 11 at 7:12
Thank you. You correction to problem 1 actually fixed all both issues. I see all values return to me when I submit the form now too. Thank you!
– Igor Vishnevskiy
Nov 11 at 7:28
Thank you. You correction to problem 1 actually fixed all both issues. I see all values return to me when I submit the form now too. Thank you!
– Igor Vishnevskiy
Nov 11 at 7:28
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53246132%2fangular-7-need-help-understanding-issues-i-face-when-building-a-form-with-mult%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown