Show varying mat-options based on the selected value of another mat-select

When selecting a continent from the first mat-select, only the countries belonging to that continent should appear in the second mat-select options. For example, if Asia is chosen as the continent, only Asian countries should be displayed.

<div class="form">
 <mat-form-field>
  <mat-label>Continents</mat-label>
  <mat-select>
   <mat-option *ngFor="let continent of formData" [value]="continent.Continent">{{ continent.Continent }}</mat-option>
  </mat-select>
 </mat-form-field>

 <mat-form-field>
  <mat-label>Countries</mat-label>
  <mat-select>
   <mat-option *ngFor="let country of selectedContinent.Countries" [value]="country">{{ country }}</mat-option>
  </mat-select>
 </mat-form-field>
</div>

Below is an example of the data structure used:

export const formData = [
{
 Continent: "Africa",
 Countries: [
  "Nigeria",
  "Egypt",
  "Ethiopia"
 ]
},
{
 Continent: "Europe",
 Countries: [
  "Sweden",
  "Italy",
  "Hungary"
 ]
},
{
 Continent: "North America",
 Countries: [
  "United States of America",
  "Canada",
  "Mexico"
 ]
},
{
 Continent: "South America",
 Countries: [
  "Peru",
  "Argentina",
  "Colombia"
 ]
},
{
 Continent: "Asia",
 Countries: [
  "Malaysia",
  "Iran",
  "Japan"
 ]
},
{
 Continent: "Australia/Oceania",
 Countries: [
  "Fiji",
  "Australia",
  "New Zealand"
 ]
}
];

Answer №1

I don't have a lot of experience with Angular, but from what I understand, you need to extract the value of <mat-select>. The most effective way to achieve this is by utilizing Angular's two-way binding syntax, which can be found here. Additionally, it's important to modify your countries selector so that it filters the results based on the selected continent.

Applying the information provided above, here is how it would appear in your scenario:

In your component .html:

...
  <mat-select [(value)]="selectedContinent">
     <mat-option *ngFor="let continent of formData" [value]="continent.Continent">{{ continent.Continent }}</mat-option>
  </mat-select>
...
  <mat-select>
   <mat-option *ngFor="let continent of filteredFormData" [value]="continent.Countries">{{ country.Countries }}</mat-option>
  </mat-select>
...

In your component .ts:

...
  selectedContinent?: string;
  get filteredFormData() {
    // If no option is selected, selectedContinent will be undefined
    // In this case, all continents are returned
    if (!selectedContinent) return formData;
    // Filter out continents that do not meet the criteria
    return formData.filter(entry => entry.Continent === this.selectedContinent);
  }
...

You could also integrate filtering directly into your second selector using *ngIf.

Answer №2

To begin, define a variable to store the selected entry, such as selectedContinent. Next, bind this variable to the first select element and use it to populate the second select element with countries:

<div class="form">
 <mat-form-field>
  <mat-label>Continents</mat-label>
  <mat-select [(ngModel)]="selectedContinent">
   <mat-option *ngFor="let continent of formData" [value]="continent">{{ continent.Continent }}</mat-option>
  </mat-select>
 </mat-form-field>

 <mat-form-field>
  <mat-label>Countries</mat-label>
  <mat-select>
   <mat-option *ngFor="let country of selectedContinent.Countries" [value]="country">{{ country }}</mat-option>
  </mat-select>
 </mat-form-field>
</div>

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

Updates to Providers in the latest release of Angular 2

When working with angular 2.0.0-rc.1, we implemented a Provider using the new Provider method as shown in the code snippet below: var constAccessor = new Provider(NG_VALUE_ACCESSOR, { useExisting: forwardRef(() => EJDefaultValueAccessor), ...

Error: The lockfile and package.json file are not synchronized when running npm

Having a problem with NPM where the package-lock and package.json files are out of sync. Tried deleting node_modules, running npm install, but issue persists. Any suggestions? Error: npm ci can only install packages when package.json and package-lock.json ...

Create collaborative documents with serverless TypeScript extension

Utilizing Amazon Lambda AWS along with Serverless and the Serverless Plugin TypeScript to develop my TypeScript files has been quite a challenge. I have implemented shared code in my project, organized within folders such as: /shared: shared1.ts, shared2. ...

Troubleshooting `TypeError: document.createRange is not a function` error when testing material ui popper using react-testing-library

I am currently working with a material-ui TextField that triggers the opening of a Popper when focused. My challenge now is to test this particular interaction using react-testing-library. Component: import ClickAwayListener from '@material-ui/core/ ...

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 ...

Angular - The element contains an implicit 'any' type due to the absence of an index signature in the 'AbstractControl' type

Within my Angular-11 project, I am utilizing the following TypeScript code: multistep = new FormGroup({ userDetails: new FormGroup({ first_name: new FormControl(''), last_name: new FormControl(''), other_na ...

Discovering class methods in typescript

Currently, I am running TypeScript unit tests using Mocha Chai after configuring the compiler options to ts-node. Within one of my unit tests, I am seeking a way to retrieve all methods from a utility class that I have designed and execute the same set of ...

Instructions for adding a name to a string based on certain conditions

I am attempting to prepend a company name to a card number using the code provided. The challenge I am facing is incorporating the specific rules for each company as conditions for an if statement. Although I acknowledge that my current approach with the ...

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 ...

The utilization of a Typescript Generic for basic addition is not producing the desired results

This issue feels incredibly insignificant, but for some reason I can't seem to figure out why it's not functioning correctly. It seems like the return type should match since I am simply concatenating or adding based on whether it's a number ...

The error message "registerNgModuleType: Uncaught TypeError: Cannot read property 'id' of undefined" indicates that there is an issue

I am facing an issue with my Angular app repository. After cloning the repository, installing the node_module, and running ng serve, I encounter an error. Despite searching for numerous solutions, none seem to be effective. The app is built on Angular 8.1, ...

What is the process for sharing an Angular-CLI project as an NPM package?

I am developing a custom Angular 2 module using Angular-CLI. What is the process for preparing the module for importing? And, how can I publish the final output to NPM in order to make it accessible for other Angular 2 projects? ...

Attempting to integrate Bootstrap 5 accordion into Angular 17 using ngFor has posed a challenge for me

<div class="accordion w-50 mx-auto" id="accordionExample"> <div *ngFor="let note of notes; index as i;"> <div class="accordion-item"> <h2 class="accordion-header" id="headi ...

Steps for incorporating a toggle feature for displaying all or hiding all products on the list

Looking for some guidance: I have a task where I need to display a limited number of products from an array on the page initially. The remaining items should only be visible when the user clicks the "Show All" button. Upon clicking, all items should be rev ...

Is it possible to initialize multiple Observables/Promises synchronously in ngOnInit()?

I am relatively new to Angular/Typescript and facing a challenge. In my ngOnInit(), I am trying to fetch settings from my backend using a GET request. After that, I need to subscribe to an observable. The observable updates the widgets' content over t ...

Creating a Personalized Color Palette Naming System with Material UI in TypeScript

I have been working on incorporating a custom color palette into my material ui theme. Following the guidance provided in the Material UI documentation available here Material UI Docs, I am trying to implement this feature. Here is an excerpt from my cod ...

Trouble with querying NG elements using "queryAll(By.css)" in Angular and Jasmin unit testing

I've encountered an unusual problem that needs to be resolved for me to successfully complete a unit test for a project I'm currently engaged in. Here is what my unit test currently looks like: it('should display the navbar list', ...

Troubleshooting Firebase: How come my code is only accessing the initial document in my Collection?

After spending hours searching, I still can't find a solution to my problem with this code. The Firebase log file only shows: "after for each =undefinedsensor_location_1undefinedundefinedundefined " Why is it only referencing the first do ...

Automatically generate a component and seamlessly integrate it into your git repository

How can I automatically generate a component in Angular CLI (2^) and add it to Git without having to manually add each generated component using an IDE or CMD? ...

A guide on incorporating jQuery alert messages into Angular 2

Whenever I submit a form by clicking on the "send message" button, I want to display an Alert message using jQuery. However, currently, I have to double click for the alert message to appear. How can I make it so that the alert message is shown with just o ...