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

Angular Reactive Form - How to use FormArray with FormGroup(s)

Discussão em 'Angular' iniciado por Damon, Outubro 16, 2024 às 04:22.

  1. Damon

    Damon Guest

    I am trying to mimic my model in my reactive form. I've set up a few FormGroups to "nest" things that make sense according to my model. I'm having trouble setting up my component to read the values--which suggests that I likely don't have my template set up correctly either.

    Depending if I am editing an existing location or creating a new one,

    @Input() location: ILocation;


    could be undefined. Currently, I am only focused on working with an existing location, so I know location has value.

    // location.model.ts

    name: string;
    ...
    messaging: [
    {
    email: {
    fromName: string;
    fromAddress: string;
    };
    }
    ];
    ...
    createdAt?: string;
    updatedAt?: string;
    deletedAt?: string;


    In my template I am using ngClass to give the user validation feedback:

    // location.commponent.html

    <div formGroupName="messaging">
    <div formGroupName="email">
    ...
    <div [ngClass]="form.get(['messaging', 'email', 'fromName'])!.errors && (form.get(['messaging', 'email', 'fromName'])!.dirty || form.get(['messaging', 'email', 'fromName'])!.touched) ? 'red' : 'green'">
    <input name="fromName"/>
    </div>
    <!-- fromAddress -->
    </div>
    </div>


    In my component, I am passing the model in with input binding, then setting up my form group(s) and form fields like this:

    // location.component.ts

    @Input() location: ILocation;

    form: FormGroup;

    ...

    ngOnInit(): void {
    this.form = new FormGroup({name: new FormControl(this.location.name, [Validators.required]),
    messaging: new FormGroup({
    email: new FormGroup({
    fromName: new FormControl(this.location.messaging[0].email.fromName, [Validators.required]),
    fromAddress: new FormControl(this.location.messaging[0].email.fromAddress, [Validators.required]),
    }),
    }),
    }



    The error I am seeing is:


    Cannot read properties of undefined (reading 'email')

    If I log out what is in the component:

    console.log('messaging: ', this.location.messaging);

    // email: {fromName: 'No Reply <noreply@example.com>', fromAddress: 'noreply@example.com'}


    I've tried various methods of messaging['email'] or messaging.email messaging[0] but I can't find the correct path.

    I am also not sure if I am using the get() method correctly in my template.

    How can I set up my form to correctly read/present the data?

    Update:

    Not surprisingly, a big problem I was having was sending the wrong shape of data back.

    In the end, this is the JSON I am trying to create:

    [{"email":{"fromName":"No Reply <noreply@example.com>","fromAddress":"noreply@example.com"}}]


    It looks like I need to use FormArray to send the proper shape:

    messaging: new FormArray([
    new FormGroup({
    email: new FormGroup({
    fromName: new FormControl(this.location.messaging[0].email.fromName, [Validators.required]),
    fromAddress: new FormControl(this.location.messaging[0].email.fromAddress, [Validators.required]),
    }),
    }),
    ]),


    This is causing some trouble in my template as I'm currently doing this: form.get('messaging[0].email.fromAddress')

    Resulting in:


    Error: Cannot find control with path: 'messaging -> email'

    I think I need to somehow loop through the FormArray. This really isn't a dynamic array though. I'll always have email and only fromName and fromAddress.

    Continue reading...

Compartilhe esta Página