Reputation: 13367
I hope you can help me out with this. I have a form which allows me to dynamically add items to an array, the array can be pre-populated if we are editing and looks something like this:
<mat-list class="hall-list"
*ngIf="f.halls.length">
<mat-list-item *ngFor="let hall of f.halls.controls;">
<ng-container [formGroup]="hall">
<img [src]="hall.url"
matListAvatar />
<p matLine>{{ hall.url }}</p>
<p matLine>{{ hall.startTime }}</p>
<p matLine>
<mat-form-field class="full-width-field">
<mat-label for="url">Start time *</mat-label>
<input matInput
placeholder="Enter the start time"
formControlName="startTime">
</mat-form-field>
</p>
</ng-container>
</mat-list-item>
</mat-list>
As you can see I am trying to display an image based on the url of the "hall". I have set that up as follows:
ngOnInit() {
this.buildForm();
this.getHall();
}
get f() {
return this.form.controls;
}
private buildForm(): void {
this.form = this.formBuilder.group({
videoUrl: ["", Validators.required],
tags: ["", Validators.required],
halls: this.formBuilder.array([])
});
}
private getHall(): void {
this.querySubscription = this.route.queryParams.subscribe(params => {
const id = params.hallId || 0;
const halls = this.form.controls.halls as FormArray;
if (id) {
this.hallService.get(id, "Videos").subscribe(hall => {
const group = new FormGroup({
id: new FormControl(hall.id),
url: new FormControl(hall.url, Validators.required),
startTime: new FormControl("", Validators.required)
});
halls.push(group);
});
}
});
}
But when I view my page, although I get no errors, it does not display an image. I added the <p matLine>
to try to debug, but they are empty also.
Does anyone know what I am doing wrong?
Just because some people are stating errors, here is the total html file:
<form [formGroup]="form"
(ngSubmit)="save(form.value)"
novalidate>
<app-stepper #stepper>
<app-step name="Video"
[expanded]="stepper.step === 0">
<mat-form-field class="full-width-field">
<mat-label for="videoUrl">Youtube link *</mat-label>
<input matInput
placeholder="Enter a valid image url"
formControlName="videoUrl">
</mat-form-field>
<app-tags (change)="onChangeTags($event)"></app-tags>
<mat-action-row>
<button mat-raised-button
type="button"
color="primary"
(click)="getSnippet()"
[disabled]="!f.videoUrl.valid || !f.tags.valid">Next</button>
</mat-action-row>
</app-step>
<app-step name="Halls"
[expanded]="stepper.step === 1"
[disabled]="stepper.step < 1">
<p>Chanell: {{ model?.channelTitle }}</p>
<p>Title: {{ model?.title }}</p>
<mat-list class="hall-list"
*ngIf="f.halls.length">
<div formArrayName="halls">
<mat-list-item *ngFor="let hall of f.halls.controls;">
<ng-container [formGroup]="hall">
<img [src]="hall.url"
matListAvatar />
<p matLine>{{ hall.url }}</p>
<p matLine>{{ hall.startTime }}</p>
<p matLine>
<mat-form-field class="full-width-field">
<mat-label for="url">Start time *</mat-label>
<input matInput
placeholder="Enter the start time"
formControlName="startTime">
</mat-form-field>
</p>
</ng-container>
</mat-list-item>
</div>
</mat-list>
<app-image-previewer [files]="files"
[urls]="urls"
[progress]="progress"></app-image-previewer>
<mat-action-row>
<app-file [files]="files"
[urls]="urls"></app-file>
<button mat-raised-button
type="submit"
color="primary"
[disabled]="!form.valid || !f.halls.length">Save</button>
</mat-action-row>
</app-step>
</app-stepper>
</form>
Here is a stackblitz showing the issue: https://angular6-dynamic-form-array-vnnye9.stackblitz.io
Upvotes: 0
Views: 921
Reputation: 9084
With reference to the latest stackblitz code you have provided, the value of the image src
is null and you can set the value using the reference from the formgroup to array level and with each index like myForm.value.arr[i].url
..
Hence
Change,
<div><img [src]="url" alt="some url" /></div>
To:
<div><img [src]="myForm.value.arr[i].url" alt="some url" /></div>
Reason for the change:
You are iterating an array to display a url
which doesn't have any value so it gives null..
You can look at the image below,
Here normally to retrieve the form values we use, {{myForm.value | json}}
which will give the json format of the formvalue so using that you need to find out where exactly does the url lies, then you can find out the path.
So here in your case it is available here myForm.value.arr[i].url
.. We need to access it from the form level object to array with index then url of that item.
Upvotes: 1
Reputation: 96
Possible problems:
In your html file:
<mat-list class="hall-list" *ngIf="f.halls.length">
<div formArrayName="halls">
<mat-list-item *ngFor="let hall of f.halls.controls; index as i">
<ng-container [formGroup]="i">
<img [src]="hall.value.url"
matListAvatar />
<p matLine>{{ hall.value.url }}</p>
<p matLine>{{ hall.value.startTime }}</p>
<p matLine>
<mat-form-field class="full-width-field">
<mat-label for="url">Start time *</mat-label>
<input matInput
placeholder="Enter the start time"
formControlName="startTime">
</mat-form-field>
</p>
</ng-container>
</mat-list-item>
</div>
</mat-list>
Upvotes: 1
Reputation: 41543
You should be using formArrayName
<mat-list class="hall-list"
*ngIf="f.halls.length">
<div formArrayName="halls">
<mat-list-item *ngFor="let hall of f.halls.controls;">
<ng-container [formGroup]="hall">
<img [src]="hall.url"
matListAvatar />
<p matLine>{{ hall.url }}</p>
<p matLine>{{ hall.startTime }}</p>
<p matLine>
<mat-form-field class="full-width-field">
<mat-label for="url">Start time *</mat-label>
<input matInput
placeholder="Enter the start time"
formControlName="startTime">
</mat-form-field>
</p>
</ng-container>
</div>
</mat-list-item>
</mat-list>
Upvotes: 0