0

I'm encountering an issue with an Angular application where I have a FormArray representing a list of selected items. When I select items from a list and then deselect them, undefined values are left in the FormArray.

I've implemented a toggle function that should add or remove items from the FormArray, and it mostly works, but when I remove an item, it's not properly cleaned up, and I end up with undefined values in the array.

Here's a simplified version of the relevant code:

My .ts file

export class LlamadoComponent {
 form: FormGroup;
  tipos: GenericData[] = [];
  lugares: GenericData[] = [];
  fuentes: GenericData[] = []



  constructor(private fb: FormBuilder, private placeService: CrudService) { //instancia el formulario
    //I get tipos from my service
    this.placeService.getTipos().subscribe(
      (tipos: GenericData[]) => {
        this.tipos = tipos;
      },
      (error: any) => {
        console.error('Error al obtener la lista de tipos:', error);
      }
    );

    this.placeService.getLugares().subscribe(
      (lugares: GenericData[]) => {
        this.lugares = lugares;
      },
      (error: any) => {
        console.error('Error al obtener la lista de tipos:', error);
      }
    );
    this.placeService.getFuente().subscribe(
      (fuentes: any[]) => {
        this.fuentes = fuentes;
      },
      (error: any) => {
        console.error('Error al obtener la lista de tipos:', error);
      }
    );



    // Init FormGroup here
    this.form = new FormGroup({
      nroLicitacion: new FormControl(''),
      extracto: new FormControl(''),
      nombreLicitacion: new FormControl(''),
      tipoLicitacion: new FormControl(''),
      fecha: new FormControl(''),
      hora: new FormControl(''),
      lugar: new FormControl(''),
      presupuesto: new FormControl(''),
      plazo: new FormControl(''),
      financiamiento: this.fb.array([]),
      operatoria: new FormControl(''),
      porLotes: new FormControl(''),
      gdeba1: new FormControl(''),
      gdeba2: new FormControl(''),
      gdeba3: new FormControl(''),
      gdeba4: new FormControl(''),
      // falta partidos seleccionados, ver estructura  
      lugarConsulta: new FormControl(''),
      lugarAdquisicion: new FormControl(''),
    });

    

  }



  get financiamientoArray(): FormArray {
    return this.form.get('financiamiento') as FormArray;
  }

  toggleFinanciamiento(id: number): void {
    const index = this.financiamientoArray.controls.findIndex(
      (control: AbstractControl<any, any>) => control.value === id
    );

    if (index !== -1) {
      // Si ya está seleccionado, deselecciónalo y elimina el control
      this.financiamientoArray.removeAt(index);
    } else {
      // Si no está seleccionado, agrégalo como nuevo control
      this.financiamientoArray.push(new FormControl(id));
    }

    // Actualiza el valor del FormArray con los valores actuales
    this.form.get('financiamiento')?.setValue(this.financiamientoArray.value);
  }`

And this is the html where I´m building my multiple select check
<h3 class="panel-title">Financiamiento</h3>
              <div class="checkbox-financiamiento">
                <mat-form-field>
                  <mat-label>Financiamiento</mat-label>
                  <mat-select multiple>
                    <mat-option *ngFor="let fuente of fuentes" [value]="fuente.id" (click)="toggleFinanciamiento(fuente.id)">
                      {{ fuente.descripcion }}
                    </mat-option>
                  </mat-select>
                </mat-form-field>
              </div>

CHATGPT suggested me the function toggleFinanciamiento but I´m still having undefined value problem

1 Answer 1

0

You should use formArray.controls.remove or push https://blog.angular-university.io/angular-form-array/

toggleFinanciamiento(id: number): void {
const index = this.financiamientoArray.controls.findIndex(
  (control: AbstractControl<any, any>) => control.value === id
);

if (index !== -1) {
  // Si ya está seleccionado, deselecciónalo y elimina el control
  this.financiamientoArray.controls.removeAt(index);
} else {
  // Si no está seleccionado, agrégalo como nuevo control
  this.financiamientoArray.controls.push(new FormControl(id));
}

// Actualiza el valor del FormArray con los valores actuales
this.form.get('financiamiento')?.setValue(this.financiamientoArray.value);

}`

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.