Using Angular 2 to submit ngModel data within an ngFor loop

When submitting the form, an error occurs when trying to repopulate the data back to the form:

ERROR TypeError: Cannot read property 'id' of undefined

This is in reference to the code snippet:

<select [(ngModel)]="insurer.group.id" name="group" id="group">

Template:

<form #insurerForm="ngForm" (ngSubmit)="save(insurerForm)">
    {{insurer|json}}

    <select [(ngModel)]="insurer.group.id" name="group" id="group">
        <option *ngFor="let group of groups" 
                [value]="group.id"
                [selected]="insurer.group ? insurer.group.id === group.id : null">
            {{group.name}}
        </option>
    </select>
    <button type="submit" class="dd_button">Save</button>
</form>

Insurer object:

{
  "is_admin": null,
  "type": "insurer",
  "group": {
    "id": 13,
    "email": null,
    "name": "Generic"
  }
  ...
}

Component:

export class InsurerDetailsComponent implements OnInit {

    constructor(
        private route: ActivatedRoute,
        private apiService: ApiService,
        private location: Location
    ) { }

    ngOnInit(): void {
        this.getInsurer();
    }

    groups: Group[];
    insurer: Insurer;

    getInsurer(): void {
        const id = +this.route.snapshot.paramMap.get('id');
        this.apiService.getOne(id, 'insurer', 'group').subscribe(insurer => {
            this.insurer = insurer;
        });
        this.apiService.getMany('group').subscribe(groups => 
        {
            this.groups = groups
        });
    }

    save(form: NgForm): void {
        console.log('trying to save data: ', this.insurer);
        console.log('form save data: ', form.value);

        // this.apiService.update('insurer', this.insurer.id, form.value).subscribe(insurer => this.insurer = insurer);
    }

}

I am encountering difficulties with what seems to be the form attempting to repopulate using the submitted form data. The issue lies in ngModel listening for insurer.group.id, which does not exist. I tried changing ngModel to [(ngModel)]="group.id" and [(ngModel)]="group", but it did not populate on page load.

I attempted to inspect the insurer object by displaying it as JSON with {{insurer|json}}, but I do not see any changes after saving. I am unsure how to debug with accurate data.

I also tried updating the values of the insurer object hoping it would reflect with the following code:

save(form: NgForm): void {
    this.insurer.group.id = form.value.group;
}

I am unsure about how to resolve the error and maintain the data populating on initial load. Modifying [(ngModel)]="insurer.group.id" to [(ngModel)]="group" resolves the error, but then the data is not set upon load even if I adjust the value attribute accordingly.

Answer №1

Here is one method you can use to initialize the insurer property with an Insurer instance:

 insurer: Insurer = new Insurer(); // This should be part of your implementation

Alternatively, you can initialize it like this:

 insurer: Insurer = {group:{id:1}}; 

*ngIf Directive

Utilize *ngIf to display the form element only if the insurer has been initialized.

<form #insurerForm="ngForm" (ngSubmit)="save(insurerForm)" *ngIf="insurer && insurer.group">
    {{insurer|json}}

    <select [(ngModel)]="insurer.group.id" name="group" id="group">
        <option *ngFor="let group of groups" 
                [value]="group.id">
            {{group.name}}
        </option>
    </select>
    <button type="submit" class="dd_button">Save</button>
</form>

You don't need to manually mark the selected option - ngModel will handle this for you automatically

[selected]="insurer.group ? insurer.group.id === group.id : null"

Check out the StackBlitz demo here!

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Excess whitespace found in string within mat-option

Every time I retrieve text from the mat-option, I notice an additional space at the end of the string. This causes my assertion to fail when trying to compare it with the expected value. This issue is new to me, and I'm unsure how to address it. Why ...

Angular Error: The first argument has a property that contains NaN

Struggling with a calculation formula to find the percentage using Angular and Typescript with Angularfire for database storage. Encountered an error stating First argument contains NaN in property 'percent.percentKey.percentMale. The properties are d ...

I am encountering a problem with my Material UI react-swipeable-views while using TypeScript

It seems that there is a mismatch in the version of some components. import * as React from "react"; import { useTheme } from "@mui/material/styles"; import Box from "@mui/material/Box"; import MobileStepper from "@mui/ma ...

Upgrade your AngularJS Directive to an Angular 2.x+ Directive by using an HTML decorator

Is it no longer possible to utilize Angular directives as what I like to refer to as "HTML decorators"? I found this method extremely useful in Angular 1.x when transitioning legacy applications to Single Page Apps by creating a set of directives to enhan ...

Customizing the Position of Material UI Select in a Theme Override

I'm trying to customize the position of the dropdown menu for select fields in my theme without having to implement it individually on each select element. Here's what I've attempted: createMuiTheme({ overrides: { MuiSelect: { ...

What are the steps to implement cp-react-tree-table in my application?

Recently diving into TypeScript, I decided to explore the demo provided by https://www.npmjs.com/package/cp-react-tree-table in order to incorporate this control into my project. However, I encountered some unexpected information. After conducting a thoro ...

What are the steps for running an Angular 7 application on both Android and iOS devices?

Currently in the process of developing an application using Angular 7. Any tips on ensuring optimal performance on mobile devices? The app functions smoothly on desktops in aot mode; however, loading time on Android devices is exceedingly slow (approximat ...

slider malfunctioning when dir="rtl" is used

Looking to incorporate Arabic language support into an Angular Material site, but encountering issues with the mat slider when applying dir="rtl". The problem arises when dragging the thumb in a reverse direction. I attempted a solution that resulted in a ...

What is the reason for an optional object property being assigned the 'never' type?

I'm having trouble understanding the code snippet below: interface Example { first?: number, second?: { num: number } } const example: Example = { first: 1, second: { num: 2 } } function retrieveValue<Object, Key exte ...

What is the process for transforming a nested dictionary in JSON into a nested array in AngularJS?

I am looking to create a form that can extract field values from existing JSON data. The JSON I have is nested with dictionary structures, but I would like to convert them into arrays. Is there a way to write a recursive function that can retrieve the key ...

Change an ISO date format to DD:MM:YYYY HH:MM using Angular

I currently have my date in this format: 2022-11-21T21:07:56.830-07:00 However, I am looking to convert it to the following format: 21/11/2022 07:56 ...

The 'required' validator in Mongoose seems to be malfunctioning

I've been attempting to validate the request body against a Mongoose model that has 'required' validators, but I haven't been successful in achieving the desired outcome so far. My setup involves using Next.js API routes connected to Mo ...

Dot notation for Typescript aliases

Here are the imports I have in my TypeScript source file: import {Vector as sourceVector} from "ol/source"; import {Vector} from "ol/layer"; This is how Vector is exported in ol/source: export { default as Vector } from './source/ ...

List the attributes that have different values

One of the functions I currently have incorporates lodash to compare two objects and determine if they are identical. private checkForChanges(): boolean { if (_.isEqual(this.definitionDetails, this.originalDetails) === true) { return false; ...

Include a bank account for connecting to Stripe custom accounts

Currently, I am implementing Stripe Connect using Node.js and TypeScript for a platform that facilitates payments for third-party services referred to as "partners." Our decision to utilize Stripe Connect's custom accounts gives us complete control ov ...

Is there a way to tally the checked mat-radio-buttons in Angular?

I am seeking a way to determine the number of radio buttons checked in a form so I can save that number and transfer it to a progress bar. <mat-radio-group name="clientID" [(ngModel)]="model.clientID"> <mat-radio-button *ngFor="let n of CONST ...

Retrieve the instance from the provider using its unique key without needing to inject its dependencies

I created a custom class called PermissionManager, which takes a list of Voter interfaces as an input in its constructor. export interface Voter { vote(): bool; } export class PermissionManager { constructor(private readonly ...

Troubleshooting: Inability of Angular2 Component to access class property within template

Here is the code snippet that I am currently working with: post.component.ts: import { Component } from '@angular/core'; import { Router } from '@angular/router'; import { JobsService } from '../jobs.service'; @Component({ ...

Tips for creating the perfect ngrx state structure

Currently, I am working on adding a new feature state that includes a graph state with two subfeatures: node state and link state. Here is how I have implemented the graph state and reducer: export interface GraphState { [fromNode.featureKey]: fromNode ...

Navigating the maze of Material UI in React with TypeScript

I have a functioning code, but I am trying to incorporate Material UI into it. However, when I replace 'input' with 'TextField', I encounter the following error: Uncaught (in promise) Error: Request failed with status code 422 at cr ...