Tips for dynamically incorporating filtered selections into a Mat-Select dropdown

I am seeking guidance on how to prevent changing the values of already selected values in other rows when each row of the formArray is altered. Adding controls dynamically and correctly retrieving values in filters are functioning properly. The issue arises when altering a row, causing changes in other dropdowns as well. Your assistance is greatly appreciated.

Currently, I have successfully implemented a FormArray where controls are dynamically added with the click of a button. These controls consist of two dropdowns, with the second dropdown's value dependent on the selection made in the first dropdown.

However, upon adding a new dynamic control and modifying the second dropdown's value, it also resets the value of previously selected values in the other dropdowns. The dropdowns are being rendered using material <mat-select>.

Here is a snippet of my HTML:

<!-- HTML code here -->

The method onAddCars() is responsible for adding new controls to the allocationsArray.

In my TypeScript file, the filterCarModel method is used to filter the second control values based on the selected value in the first row of the allocationsArray. Here is an example:

<!-- TypeScript code here -->

If you could provide insight into how to ensure that each row of the formArray does not alter the values of already selected values in other rows, I would greatly appreciate it. Thank you.

Answer №1

Utilize a unique variable called "subModels" across all form elements for better organization.

One approach is to structure subModels as an array or arrays.

//declare subModels as array of any
subModels:any[]=[]
public filterCarModel(e:any,ind:any)
  {
    let index = <FormArray>this.allocationForm.controls['allocationsArray'];
    var carList = Array.from(new Set(this.productsDTO.filter(x => x.productType === e.value).sort().values()));

    //here declare this.subModels[ind] as an array
    this.subModels[ind] = Array<Productdropdown>();

    carList.forEach(productLists => {
      const tempItem = new Productdropdown();
      tempItem.displayValue = productLists["carDescription"]
      tempItem.itemValue = productLists["carCode"]

      //you push the element in this.subModels[ind]
      this.subModels[ind].push(tempItem);
    });
  }

Alternatively, consider structuring your productList as an array with children models and submodels.

modelList=[{
      id:1,
      model:'Audi',
      submodels:[{id:10,name:'A3'},{id:11,name:'Quatro'}]
      },
      {
      id:2,
      model:'Seat',
      submodels:[{id:20,name:'Ibiza'},{id:21,name:'Panda'},{id:22,name:'Leon'}]
      },
  ]

Create a formArray with model and submodel using two functions:

getLine(data:any)
  {
    data=data || {model:'',submodel:''}
    return new FormGroup({
      model:new FormControl(data.model),
      submodel:new FormControl(data.model)
    })

  }
  addLine()
  {
    this.formArray.push(this.getLine(null))
  }

To enhance usability, use an auxiliary variable and [ngModel] in the form, handling values separately from formArray controls.

Define the variable:

model:any[]=[]

Update the .html file:

<button mat-button (click)="addLine()">Add</button>
<form [formGroup]="formArray">
    <div *ngFor="let group of formArray.controls;let i=index" [formGroup]="group">
        <mat-form-field>
            <mat-label>Model</mat-label>
            <mat-select [ngModel]="model[i]"
             (ngModelChange)="model[i]=$event;group.get('model').setValue($event.id)"
             [ngModelOptions]="{standalone:true}"
             >
                <mat-option *ngFor="let modelo of modelList" [value]="modelo">
                    {{modelo.model}}
                </mat-option>
            </mat-select>
        </mat-form-field>
        <mat-form-field>
            <mat-label>SubModel</mat-label>
            <mat-select formControlName="submodel">
                <mat-option *ngFor="let submodelo of model[i]?.submodels" [value]="submodelo.id">
                    {{submodelo.name}}
                </mat-option>
            </mat-select>
        </mat-form-field>

    </div>
</form>

For a live example, visit stackblitz

Answer №2

Eliseo, your answer pointed me in the right direction and I appreciate that. Here is the updated code that reflects the changes I made:

<mat-option *ngFor="let subModel of subModels[i]" [value]="subModel.itemValue">
                      {{subModel.displayValue}}
                    </mat-option>

I also added an array for subModelsAny[][]=[]; Although I followed a different approach using FormArray instead of your suggestion, it still worked out well.

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

Using `setTimeout` in a recursive function that is nested within another function

I am attempting to use setTimeout in a recursive function call where the main function is called recursively and subfunctions are also called recursively. Below is the code I am working on: this.myArray = Array(2).fill(undefined); StartFunction(len: numb ...

Exploring Angular 2 - examining how @input is implemented within the ngOnInit lifecycle hook for testing a component

Presently, I am facing a challenge while attempting to test a child component that is designed to receive input from the host component and utilizes the ngOnInit lifecycle hook as depicted in the following code snippet. @Component({ selector: 'my ...

What is the best way to simulate a service HTTP request using Jasmine in an Angular application?

Why is my spy not working as expected? I've set up a spy for the prescriptionService and am monitoring the fetchClientPrescriptions method, but when I try to verify if it has been called, I encounter an error. However, the spy for getClientPrescriptio ...

Can you explain the significance of the @ symbol in TypeScript/Vue?

I've recently embarked on a new VueJS project and stumbled upon some unfamiliar syntax. I have highlighted the lines with comments below. file(example) : MyModule.vue const storeCompte = namespace("compte") // namespace is based on 'no ...

Encountering a NgForm provider error in Angular 4.4.6 development mode

UPDATE: Identifying the root of the issue has led me to search for a suitable solution. NOTE: This complication is specific to development mode (not production, and not utilizing AOT). The "Update" resolution I am implementing can be found here. In an a ...

Having trouble with RouterExtension.back() in Nativescript Angular?

I've created a module called TransactionModule that consists of the following routes: transaction-routing.module.ts export const routes: Route[] = [ { path: 'transaction', component: TransactionComponent, canActivate: [AuthGu ...

implementing a directive in an Angular 2 component

Just finished putting together a basic project with angular 2. Ran into an issue when attempting to include a directive component in the app.component - getting a red underline under the 'directives' property. Anyone out there know what's go ...

Glitch causing incorrect images to appear while scrolling through FlashList

Currently, I am using the FlashList to showcase a list of items (avatars and titles). However, as I scroll through the list, incorrect images for the items are being displayed in a mixed-up manner. Based on the explanation provided in the documentation, t ...

What's causing Angular to not display my CSS properly?

I am encountering an issue with the angular2-seed application. It seems unable to render my css when I place it in the index.html. index.html <!DOCTYPE html> <html lang="en"> <head> <base href="<%= APP_BASE %>"> < ...

Utilizing References in React Components

One of the challenges I am facing involves a Container that needs references to some of its child components: const Container = () => { const blocks: HTMLDivElement[] = []; return ( <div> <Navigation currentBlock={currentBlock} ...

Error in displaying dialogues upon clicking

Currently experimenting with creating a dialog modal using the tutorial found at https://github.com/gopinav/Angular-Material-Tutorial/tree/master/material-demo/src/app, specifically referring to the dialog-example and dialog folder. However, upon testing ...

Patience is key as you await the completion of an API call in Angular 14

Within my Angular 14 application, I am faced with a scenario where I need to make two API calls and then combine the results using "combineLatest" from rxjs. The combined data is then assigned to a variable that I must use in a separate function. How can I ...

Google Cloud PubSub does not automatically resend unacknowledged messages

The answer chosen for this particular question contains some pertinent details I currently have a subscription set up with the following parameters: https://i.stack.imgur.com/Bn0d4.png along with the following code snippet: const subscription = this.pub ...

Choose several checkboxes from the dropdown menu

After clicking the dropdown, I want to select multiple checkboxes instead of just one. I have tried using the prevent default method but it did not work. Beginner concept ...

What causes the error message saying 'undefined' cannot be assigned to the specified type ...?

I just finished developing an innovative Angular application. Within the app.component.html file, I have included: <bryntum-scheduler #scheduler [resources] = "resources" [events] = "events" [columns] = "schedul ...

What could be causing the Properties Array to come back as undefined?

When attempting to add an item to an array stored in the properties, I am encountering an error: "Cannot read properties of undefined (reading 'value')." Within the props, the following interfaces are defined: ILinkItemProps.ts export interface ...

Universal variable arguments

Is there a way to modify this function that accepts generic rest parameters to also accept an array parameter without using the spread operator? This would make chaining things much clearer: function fn<T>(...args: T[]): Something<T> { } let s ...

How can we ensure that only one of two props is specified during compilation?

I've designed a customized Button component. interface Button { href?: string; action(): void; } I'm looking to ensure that when a consumer uses this Button, they can only pass either href or action as a prop, not both. I want TypeScri ...

Information about the HTML detail element in Angular 2 is provided

Hi, I'm curious if there's a way to know if the details section is open or closed. When using <details (click)="changeWrap($event)">, I can't find any information in $event about the status of the details being open. I am currently wor ...

What is causing the warnings for a functional TypeScript multidimensional array?

I have an array of individuals stored in a nested associative array structure. Each individual is assigned to a specific location, and each location is associated with a particular timezone. Here is how I have defined my variables: interface AssociativeArr ...