0

I would like to be able to dynamically create my formControl variables which corresponds to the name of my columns of my Table object without having to write hard in the createInput() method that I inject into my formArray.

I tried that but it does not work :

import { Component, OnInit } from '@angular/core'; import { ParameterService } from '../service/parameter.service'; import { Table } from '../model/table.model'; import { FormControl, FormGroup, FormBuilder, FormArray } from '@angular/forms'; import { DomSanitizer } from '@angular/platform-browser'; import { Typpar } from '../model/typpar.model'; @Component({ selector: 'app-dashboard', templateUrl: './dashboard.component.html', styleUrls: ['./dashboard.component.css'] }) export class DashboardComponent implements OnInit { typpar: Typpar; table: Table; fileUrl: any; formGroup: FormGroup; inputRows: FormArray; numberOfLineForm: FormGroup; // On injecte une instance de FormBuilder et de ParameterService en dépendance de notre component constructor(public ps: ParameterService, private formBuilder: FormBuilder, private sanitizer: DomSanitizer) { } ngOnInit() { // initialize our form using FormBuilder in the ngOnInit hook. // We’ll create a formGroup that allows the user to add new inputRows dynamically: this.formGroup = this.formBuilder.group({ inputRows: this.formBuilder.array([this.createInput()]) }); console.log(this.formGroup); this.numberOfLineForm = this.formBuilder.group({ numberOfLine: [''] }); console.log(this.numberOfLineForm); this.ps.getAllColumns().subscribe(res => { this.table = res; this.createInput(); console.log(this.table); }); this.ps.getAllParams().subscribe(res => { this.typpar = res; console.log(res); }); } // Permet de récupéer formData dans la vue qui est une instance de FormArray get formData() { return this.formGroup.get('inputRows') as FormArray; } // method to create a form group as the first inputRow in our array createInput(): FormGroup { // Comment récupérer le bon nombre de formControl qui correspondent // aux nom de mes columns de mon objet Table sans avoir à les mettres en dure console.log(this.table); if (this.table && this.table.columns.map) { this.table.columns.map((column) => { this.formGroup.addControl(column.name, new FormControl('')); }); } return this.formGroup; 

Here is my dashboard component html :

 <!--Dashboard--> <section class="section_4"> <!-- ON A NOMMÉ LE FORMULAIRE "orderForm" dans le app.component.ts --> <!-- ON utilise la directive [formGroup]='orderForm pour le lier' --> <form [formGroup]='formGroup' (ngSubmit)='submitForm(formGroup.value)' class="table"> <div class="section_5"> <div class="line"> <div class="columnName" *ngFor="let column of table?.columns">{{ column.name }}</div> </div> <!-- ICI LA DIRECTIVE formArrayName='items' permet de cibler items qui est déclaré comme un formArray dans app.component.ts formData provient de : get formData() { return <FormArray>this.orderForm.get('items'); } --> <div formArrayName="inputRows" *ngFor="let inputRow of formData.controls; let i = index; let c = count"> <div class="line" [formGroupName]="i" id="inputRow"> <!-- <span>{{i+1}} </span> --> <ng-container *ngFor="let column of table?.columns"> <select *ngIf="column?.dropdown; else noDropdown" formControlName="{{column.name}}"> <option *ngFor="let param of column?.parameters;" value="{{param.id}}">{{param.libelle}}></option> </select> <ng-template #noDropdown> <input class="myInput" formControlName="{{column.name}}" type="{{ column.type }}" name="{{column.name}}_{{i}}" maxLength="{{ column.length }}" required="{{ column.nullable }}" value="{{ column.dataDefault }}" placeholder=" "> </ng-template> </ng-container> <span><img title="Supprimer la ligne " *ngIf="c > 1" (click)="deleteInputLine($event, i)" id="deleteIcon" src="../../assets/img/cancel.png" /></span> </div> </div> </div> <br> <hr> <div class="button"> <button type="button" class="btn btn-info" (click)="addInputRow($event)">Ajouter une ligne</button> <!-- <button type="submit" class="btn btn-info">Envoyer</button> --> <a [href]="fileUrl" (click)="downloadSqlQuery()" download="sql_query.txt" class="btn btn-secondary btn-lg active" role="button" aria-pressed="true">DownloadFile</a> </div> </form> 

the console error :

enter image description here

2
  • 2
    The issue is in your html code and you are not showing that piece of code..... Commented Sep 23, 2019 at 8:30
  • I put the html code. Commented Sep 23, 2019 at 9:52

1 Answer 1

1

Your syntax is off in a few places. Don't call createInput() inside the formarray. Then you are not pushing values to your formarray, but instead pushing it to the formgroup. Then you are iterating both the formarray and your table.columns array in template. You should just iterate the formarray, and based on the index you can refer to your table.columns array. Here is a shortened minimal example of your code. Speaking of which, you should always provide a minimal sample of the issue you are facing (tip for future questions). But back to question, here are some fixes:

ngOnInit() { this.formGroup = this.formBuilder.group({ inputRows: this.formBuilder.array([]) // don't call createInput! }); } 

Your createInput function should add new formgroups to the formarray instead:

get formData() { return this.formGroup.get('inputRows') as FormArray; } // method to create a form group as the first inputRow in our array createInput() { if (this.table && this.table.columns.length) { this.table.columns.map((column) => { this.formData.push( this.formBuilder.group({ // add dynamic name with brackets [column.name]: [''] }) ); } }) 

And finally iterate the formarray in template:

<form [formGroup]='formGroup' (ngSubmit)='submitForm(formGroup.value)'> <div formArrayName="inputRows" *ngFor="let inputRow of formData.controls; let i = index;"> <ng-container [formGroupName]="i" > <input [formControlName]="table.columns[i].name" > </ng-container> </div> </form> 

DEMO: STACKBLITZ

Sign up to request clarification or add additional context in comments.

2 Comments

thank you I tried but it does not work. I'm using createInput () to inject new formcontrol into my formArray to add new lines to my array. It only works when I put the formcontrol on hard, like this :
createInput(): FormGroup { return this.formBuilder.group({ TYPEPARA: '', ID_CATEPARA: '', ID_NATUPARA: '', ID_FORMPARA: '', LIBL: '', DSCR: '', DATEDEBUEFFE: '', DATEFIN_EFFE: '', MONTCONVEURO: '', VALEDEFA: '', LIBLEXTR: '', TEXTLONG: '', REGRVALEPOSS: '', INTR: '', CODEINIT: '', VALEINIT: '', TYPONOME: '', MAXIVALE: '' }); }

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.