Search code examples
angularangular-formsangular9angular-formbuilder

Nested FormArray inside another FormArray


Heres what I'm trying to accomplish:

In a page, a user will be able to upload their protections of certain Forex Pair. So, users can select different timeframes to upload their image analysis. My form is simple:

dataForm: FormGroup;
this.dataForm = this.builder.group({
      nombre: ['', [Validators.required]],
      analisis: this.builder.array([ this.createItems() ])
    });

For create the analysis array, I use this code:

createItems() {
    return this.builder.group({
      temporalidad: [],
      descripcion: [],
      fileImg: this.builder.array([])
    });

  }

Everything works fine until I have to choose the images for the different analyses that I create. If I just choose to add another analysis card [analysis 1 & analysis 2], if I use the button to load the image for analysis one, this is displayed correctly in the analysis 1 card's... but when I choose the image of analysis 2, this is displayed in the analysis 1 card's not in analysis 2 card's

This is my code for load the image

fileUploads(evt: any, index: any) {
    const files = evt.target.files;
    const control = this.dataForm.controls.analisis['controls'][index].controls['fileImg'].controls;
    for (let i = 0; i < files.length; i++) {
      const reader = new FileReader();
      reader.onload = (e) => {
        const base64img = reader.result + '';
        control.push(this.builder.control(base64img));
      };
      reader.readAsDataURL(files[i]);
    }
    evt.srcElement.value = null;
  }

And the HTML for displayed the images

<div>
                                <label for="file-upload" class="custom-file-upload">
                                    <mat-icon class="icon">add_a_photo</mat-icon> Imagen del análisis
                                </label>
                                <input id="file-upload" name="file" type="file" (change)="fileUploads($event, i)" accept="image/png,image/jpeg,image/jpg"/>
                            </div>
                            <figure *ngFor="let image of dataForm.controls.analisis['controls'][i].controls['fileImg'].controls; let j = index" style="margin-left: 0px;">
                                <img [src]="image.value" class="proyection-image" />
                            </figure>

I post as well the Stackblitz link for you to see the functionality and understand better what I want to archive. StackBlitz Link

Thanks in advance!


Solution

  • you need to change template

    set input name and id as "file-upload{{i}}", inside of ngFor it is necessary to set unique names. there are could be various bugs

    example

    // html
    <div>
      <label for="file-upload{{i}}" class="custom-file-upload">
        <mat-icon class="icon">add_a_photo</mat-icon> Imagen del análisis
      </label>
      <input id="file-upload{{i}}" 
        name="file-upload{{i}}" type="file" 
        (change)="fileUploads($event, i);"
        accept="image/png,image/jpeg,image/jpg"/>
    </div>