1. Anuncie Aqui ! Entre em contato fdantas@4each.com.br

Accessing Angular Typed Form Property from a FormArray in the HTML Template

Discussão em 'Angular' iniciado por Wesley, Outubro 9, 2024 às 19:23.

  1. Wesley

    Wesley Guest

    I’m working on a form that manages currencies, with fields for code and label. I’m using the latest Angular features and trying to leverage typed forms.

    I have a FormArray inside a FormGroup, which is populated with some pre-filled currency data. The reactive form works as expected—I can add and remove currencies with buttons.

    [​IMG]

    However, I’m facing an issue when trying to access the form control properties in my HTML template to apply validation classes (e.g., showing a valid or invalid state for the input fields). I receive the following error:

    NG9: Property 'code' does not exist on type 'AbstractControl<any, any>'. [plugin angular-compiler]

    src/app/countries.component.html:34:58:
    34 │ [class.is-valid]="currency.code.valid"


    Problem:

    Here’s the code that triggers the error:

    [class.is-valid]="currency.code.valid"


    I’ve also tried changing it to:

    [class.is-valid]="currency.controls['code'].valid"


    Or:

    [class.is-valid]="currency.get('code').valid"


    But I still get the same error.

    My TypeScript Code:

    import { CommonModule } from '@angular/common';
    import { Component, inject, OnInit } from '@angular/core';
    import {
    FormArray,
    FormBuilder,
    FormGroup,
    ReactiveFormsModule,
    Validators
    } from '@angular/forms';

    export interface Item {
    code: string;
    label: string;
    }

    @Component({
    selector: 'app-countries',
    standalone: true,
    imports: [ReactiveFormsModule, CommonModule],
    templateUrl: './countries.component.html',
    styleUrl: './countries.component.scss'
    })
    export class CountriesComponent {
    currencyForm: FormGroup;
    private formBuilder = inject(FormBuilder);

    constructor() {
    this.currencyForm = this.formBuilder.group({
    currencies: this.formBuilder.array<FormGroup>(
    [
    {code: 'CAD', label: 'Canadian Dollar'},
    {code: 'USD', label: 'United States Dollar'},
    {code: 'EUR', label: 'Euro'}
    ].map(currency => this.createCurrencyFormGroup(currency))
    )
    });
    }

    createCurrencyFormGroup(currency: Item) {
    return this.formBuilder.group({
    code: [currency.code, [Validators.required, Validators.maxLength(3), Validators.minLength(3)]],
    label: [currency.label, Validators.required]
    });
    }

    get currencies(): FormArray {
    return this.currencyForm.get('currencies') as FormArray;
    }

    addCurrency() {
    const currencyControl = this.createCurrencyFormGroup({code: '', label: ''});
    this.currencies.push(currencyControl);
    }

    removeCurrency(index: number) {
    this.currencies.removeAt(index);
    }
    }


    My HTML Code:

    <div class="container mt-3">
    <form [formGroup]="currencyForm" class="row g-3">
    <div class="col-md-5" formArrayName="currencies">
    <button type="button" class="btn btn-sm btn-secondary" (click)="addCurrency()">Add Currency</button>

    <div *ngFor="let currency of currencies.controls; let idx = index" [formGroupName]="idx">
    <div class="row">
    <div class="col-4">
    <input type="text"
    class="form-control"
    placeholder="Currency Code"
    formControlName="code"
    maxlength="3"
    [class.is-valid]="currency.get('code').valid"
    [class.is-invalid]="currency.get('code').invalid" />
    </div>
    <div class="col-6">
    <input type="text"
    class="form-control"
    placeholder="Currency Label"
    formControlName="label"
    [class.is-valid]="currency.get('label').valid"
    [class.is-invalid]="currency.get('label').invalid" />
    </div>
    <div class="col-2">
    <button type="button" class="btn btn-danger" (click)="removeCurrency(idx)">Remove</button>
    </div>
    </div>
    </div>
    </div>
    </form>
    </div>


    What I've Tried:

    • I attempted to access the control using currency.code.valid, currency.controls['code'].valid and currency.get('code').valid, but both result in the same error.
    • It seems like Angular doesn’t recognize the control properties in this way inside the template.

    Question:

    How can I properly access the form control properties in my FormArray to apply validation classes in the template? What am I doing wrong with my approach to accessing the code and label properties?

    Thank you so much

    Continue reading...

Compartilhe esta Página