Show the values in the second dropdown menu according to the selection made in the first dropdown menu using Angular 8

My goal is to retrieve data and populate two dropdowns based on user selection. However, the code I've written isn't giving me the desired output and instead, errors are occurring. Being new to Angular, I would appreciate a review of my code. Here is the JSON data from which I am fetching information:

This is the HTTP service method I have implemented:

getAccountByApiGateway(accountType: string) {
    return this.http.get(this.serviceUrl + "/account-type/" + accountType);
  }

Here is the JSON data:

{
      "data": [
        {
          "id": "8a8080fc710cdc140171104216c2002b",
          "name": "a",
          "org": {
            "id": "8a8080c4701e557501701e6cbeed003e",
            "orgPlan": "ENTERPRISE"
          },
          "accountType": "AWS"
        },
        {
          "id": "8a80802c712a8e8301712ad32c540001",
          "name": "azure",
          "org": {
            "id": "8a8080c4701e557501701e6cbeed003e",
            "orgPlan": "ENTERPRISE"
          },
          "accountType": "AZURE"
        },
        {
          "id": "8a80802c712a8e8301712b177d2e0002",
          "name": "aws2",
          "org": {
            "id": "8a8080c4701e557501701e6cbeed003e",
            "orgPlan": "ENTERPRISE"
          },
          "accountType": "AWS"
        },
        {
          "id": "8a80802c712a8e8301712b7c3b5a0003",
          "name": "FX AWS",
          "org": {
            "id": "8a8080c4701e557501701e6cbeed003e",
            "orgPlan": "ENTERPRISE"
          },
          "accountType": "AWS"
        }
      ],
      "totalPages": 0,
      "totalElements": 0
    }

Below you can find the component's data:

    accountTypes: Type[] = [
        { value: "AWS", viewValue: "AWS" },
        { value: "AZURE", viewValue: "AZURE" }
      ];

ngOnInit() {
this.getApiGatewayAccounts();
}
changeIssueTracker(type) {
    if (type.value === "AWS") {
      this.job.issueTracker.accountType = "AWS";
    } else if (type.value === "AZURE") {
      this.job.issueTracker.accountType = "AZURE";
    }
    this.getApiGatewayAccounts();
  }
getApiGatewayAccounts() {
    this.handler.activateLoader();
    this.apiGatewayService.getAccountByApiGateway("API_GATEWAY").subscribe(
      results => {
        this.handler.hideLoader();
        if (this.handler.handle(results)) {
          return;
        }
        this.apiAccounts = results['data'];
      },
      error => {
        this.handler.hideLoader();
        this.handler.error(error);
      }
    );
  }

The template code looks like this:

<mat-form-field class="full-width">
                                <mat-select name="cloudString" placeholder="Select API Gateway">
                                    <mat-option disabled>--- Select API Gateway ---</mat-option>
                                    <mat-option *ngFor="let account of accountTypes" [value]="account.value" (click)="changeIssueTracker(type)">
                                        <span *ngIf="account.value=='AWS'">
                                            <img class="img-responsive h-75" src="assets/images/aws-small.png" />
                                        </span>
                                        <span *ngIf="account.value=='AZURE'">
                                            <img class="img-responsive h-75" src="assets/images/azure-small.png" />
                                        </span>
                                        &nbsp;&nbsp;{{ account.value}}</mat-option>
                                </mat-select>
                            </mat-form-field>

                            <mat-form-field class="full-width">
                                <mat-select name="cloudString2" [ngModelOptions]="{standalone: true}">
                                    <mat-option *ngFor="let account of apiAccounts" [value]="account.name">
                                        {{account.name}}
                                    </mat-option>
                                </mat-select>
                            </mat-form-field>

Upon clicking on the first dropdown, I encountered the following error:

core.js:4002 ERROR TypeError: Cannot read property 'value' of undefined
    at ApiGatewayComponent.push../src/app/components/manage/api-gateway/api-gateway.component.ts.ApiGatewayComponent.changeIssueTracker

Answer №1

<mat-option
  *ngFor="let account of accountTypes"
  [value]="account.value"
  (click)="changeIssueTracker(type)">

It appears that you are encountering an issue because type is not defined.

<mat-option
      *ngFor="let accountType of accountTypes"
      [value]="accountType.value"
      (click)="changeIssueTracker(accountType)">
      <span *ngIf="accountType.value=='AWS'">
        <img class="img-responsive h-75" src="assets/images/aws-small.png" />
      </span>
      <span *ngIf="accountType.value=='AZURE'">
        <img class="img-responsive h-75" src="assets/images/azure-small.png" />
      </span>
      &nbsp;&nbsp;{{ accountType.value}}
</mat-option>

To bind data to the second dropdown, you will need to filter the data retrieved from the API and then iterate over the filtered list in your form field. The current code handles an unfiltered list of API data. To implement this filtering logic, you can modify your .component.ts file as follows:

filteredAccountsByType = [];

changeIssueTracker(type: AccountType): void {
  if (type.value === "AWS") {
    this.job.issueTracker.accountType = "AWS";
  } else if (type.value === "AZURE") {
    this.job.issueTracker.accountType = "AZURE";
  }
  this.filteredAccountsByType = this.apiAccounts.filter(apiAccount => apiAccount.accountType === type.value);
}

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

What prevents TypeScript from automatically inferring tuple return types in RxJs streams?

When composing an observable stream, the map function infer is a union instead of a tuple. For instance: import { Component } from '@angular/core'; import { from } from 'rxjs'; import { map, tap } from 'rxjs/operators'; expo ...

Use vertical gaps to separate items by applying the following technique:

One of my components is designed to act as a badge. The CSS for this component includes: https://i.sstatic.net/F0QZ6.png HTML: <div class="label label-as-badge"> {{ value.Termo }} <i class="fa fa-times"></i ...

Angular CDKScrollable not triggering events

I'm having trouble making the angular CdkScrollable work when creating my own div: <div class="main-section" id="mainsection" #mainsection CdkScrollable> <div class="content" style="height: 300px; backgr ...

Emphasize the interactions within the table cells based on their corresponding column and row

I'm looking to achieve a specific interaction in my Angular Material table. I want to highlight the table cell interactions with column and row by extending the highlighting up to the column header and left to the row header. Is this something that ca ...

Avoid accessing members in Vue 3 using TypeScript that may be unsafe

Recently, we initiated the process of upgrading from Quasar v1 to Quasar v2 (moving from Vue 2 to Vue 3). In the past, this code functioned without any issues: // src/pages/myComponent.vue <script lang="ts"> import { defineComponent } from ...

Steps for Adding a JSON Array into an Object in Angular

Here is a JSON Array that I have: 0: {name: "Jan", value: 12} 1: {name: "Mar", value: 14} 2: {name: "Feb", value: 11} 3: {name: "Apr", value: 10} 4: {name: "May", value: 14} 5: {name: "Jun", value ...

Update the nest-cli.json configuration to ensure that non-TypeScript files are included in the dist directory

I've been searching for a solution for hours now: I'm developing an email service using nestJS and nest mailer. Everything was working fine until I tried to include a template in my emails. These templates are hbs files located in src/mail/templ ...

How is it possible for Typescript to let me create an object without explicitly defining all mandatory fields?

After creating a class and instantiating an object from it through the constructor, I expected to receive an error message indicating missing properties. However, despite the fact that the class description specified required fields, I was able to create a ...

Troubleshooting Date library timezone problems in Typescript locale

The TZ variable is automatically set by Node as an environment variable. When using new Date(); in TypeScript, the date returned is in GMT+0000 even though the code is being executed on a machine with a timezone of GMT+0530. I attempted to print out conso ...

The parameter type '==="' cannot be assigned to the 'WhereFilterOp' type in this argument

I'm currently working on creating a where clause for a firebase collection reference: this.allItineraries = firebase .firestore() .collection(`itinerary`); Here is the issue with the where clause: return this.allItiner ...

A function that logs a message to the console if an array contains identical values

Struggling to find equal values in my array, I've attempted several methods without success. One approach I tried involved sorting the array: var sorted_arr = this.variacaoForm.value.variacoes.sort(); // the comparing function here for (var i = 0; ...

Resetting the Angular2 poller in an ng-bootstrap accordion

I am currently utilizing a multi-dimensional array connected to a reactive poller that waits for a database state update. Interestingly, when I initially load the state once, the user interface functions as intended. However, a challenge arises when I act ...

The operation failed with a TypeError because the object does not allow the addition of the newField property

I encountered an error that says: TypeError: Cannot add property newField, object is not extensible Whenever I try to add a new key or change a value, it doesn't work and I'm not sure what the issue is. dynamicFilter; public ionViewWillEnte ...

Loading an Angular 2 application or component through an HTTP request can be done by following

Is there a way to dynamically load an Angular2 application or component from a remote server using HTTP? For example: Template: <app-local></app-local> <app-http></app-http> Sample code for AppComponent of app-local: [...] load ...

Set up a global variable for debugging

Looking to include and utilize the function below for debugging purposes: export function debug(string) { if(debugMode) { console.log(`DEBUG: ${string}`) } } However, I am unsure how to create a globally accessible variable like debugMode. Can this be ...

Guide to setting up a Cordova and TypeScript project using the command line interface

For my mobile application development, I rely on Cordova and execute cordova create MyApp in the command-line to initiate a new project. I am familiar with JavaScript but now require TypeScript for my project. Please assist me in setting up a Cordova pro ...

Tips for successfully interacting with dynamic text areas using Protractor:

My current project involves e2e testing for an Angular 4 application with Protractor. Despite my efforts, I am struggling to locate a unique id, class, name or text identifier for a specific textarea within the application code. I need assistance in find ...

Error: The type 'boolean | (() => void)' cannot be assigned to type 'MouseEventHandler<HTMLButtonElement> | undefined'

Playing audio in a NextJS app while writing code in TypeScript has been an interesting challenge. The onClick() function performs well in the development environment, triggered by npm run dev. <button onClick ={toggle}> {playing ? "Pause" : ...

Postman issue: Your username and password combination is incorrect within the MEAN stack environment

I am new to mean stack development and facing some issues. When I try to run "api/users/login" in Postman, it shows an error saying "Username or password is invalid!". Additionally, when attempting to register using "register/users/register", it gives a me ...

Can you explain what comes after the equal sign in a TypeScript object?

While browsing through this response on stackoverflow The author answered: // How I usually initialize var foo:IFoo = <any>{}; I attempted to research it online, but unfortunately, I couldn't find any information about it. Could someone expl ...