How does using ngFor and ngModel in Angular cause a change in one select to affect others?

I am looking to implement a feature where users can create multiple select dropdowns, choose options for each one, and then aggregate these selections into an array that will be sent to a parent component.

My current approach involves using an *ngFor loop to iterate over an array of strings (valueInputs) and dynamically creating a select dropdown for each element. By clicking an "add" button, a new empty string is added to the valueInputs array, allowing for more select dropdowns to be generated. Each select dropdown is bound to a specific index in the valueInputs array using ngModel.

You can view a demo of this functionality on Stackblitz: https://stackblitz.com/edit/angular-q5nwjq

Here is the code for the component:

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  valueInputs = ['', '', ''];
}

And here is the template markup:

<ng-container *ngFor="let valueInput of valueInputs; let i = index">
  <select
    [(ngModel)]="valueInputs[i]">
    <option value="" disabled>Select an option...</option>
    <option value="opt1">Option 1</option>
    <option value="opt2">Option 2</option>
  </select>
</ng-container>

<div>
  <button (click)="valueInputs.push('')">Add input</button>
  <p>Value Inputs: {{ valueInputs | json }}</p>
</div>

The issue I am facing is that when I select an option in one dropdown, it affects the options in other dropdowns as well. The selected option changes, but the underlying valueInputs array remains unchanged.

This behavior is consistent across all select dropdowns. Changing one dropdown selection automatically updates the others. Is this a bug in Angular or is there a different approach I should consider implementing?

Answer №1

Your StackBlitz project has been revised. To utilize ngFor with primitive data types, the "trackBy" function must be implemented.

Here are two key adjustments:

  trackByIdx(index: number, obj: any): any {
    return index;
  }

Update your HTML as follows:

<ng-container *ngFor="let valueInput of valueInputs; let i = index; trackBy:trackByIdx">

For further information, refer to this helpful answer.

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

Unleashing the power of TypeScript with Solid JS Abstract Class

Why am I getting an undefined error for my calcUtilisation method when using an Abstract Class as the type in createStore? Is there a way to utilize a type for the data along with a method within the same class for createStore? abstract class Account { ...

Issues with Angular 2 template not refreshing during testing

I'm struggling to get this to function properly. it('should have the expected <h1> text', async(() => { let fixture = TestBed.createComponent(AppComponent); fixture.detectChanges(); const sectionEl = fixture.debugElement.que ...

Categorizing the types of dynamically retrieved object values

I've developed a unique class with two properties that store arrays of tuples containing numbers. Additionally, I've implemented a method called "getIndex" which dynamically accesses these properties and checks for duplicate number values within ...

How Vue3 enables components to share props

Having recently made the switch from Vue2 to Vue3, I find myself a bit perplexed about the best approach for sharing props among multiple components. My goal is to create input components that can share common props such as "type", "name", and so on. Previ ...

Discover the right Angular signal using the effect() function

While I find the signals in Angular to be quite useful, I am facing a challenge when it comes to handling multiple signals. For instance, let's say we have a service called ExternalController that defines two signals: controller1 and controller2. My ...

NextJS and Context API throwing a Typescript error

I've been working on my _app.tsx file and here's the code snippet I have: import React from 'react' import type { AppProps } from 'next/app' /* Import Styles */ import '@themes/index.scss' /* Import Template */ imp ...

What is the best way to create unit tests for a React component using TypeScript?

I recently completed a small React project using TypeScript and decided to have it print numbers of li tags in the browser. During this process, I wanted to write unit tests that would test if the component created the HTML element . However, as someone ...

Neglectful TypeScript null checks overlooking array.length verification

When TypeScript is compiled with strict null checks, the code snippet below does not pass type checking even though it appears to be correct: const arr: number[] = [1, 2, 3] const f = (n: number) => { } while (arr.length) { f(arr.pop()) } The comp ...

How come TypeScript tuples support the array.push method?

In the TypeScript code snippet below, I have specified the role to be of Tuple type, meaning only 2 values of a specified type should be allowed in the role array. Despite this, I am still able to push a new item into the array. Why is the TS compiler not ...

What is the best approach for managing _app.js props when transitioning from a page router to an app router?

Recently, in the latest version of next.js 13.4, the app router has been upgraded to stable. This update prompted me to transition my existing page router to utilize the app router. In _app.jsx file, it is expected to receive Component and pageProps as pr ...

Using Typescript to collapse the Bootstrap navbar through programming

I've managed to make Bootstrap's navbar collapse successfully using the data-toggle and data-target attributes on each li element. If you're interested, here is a SO answer that explains a way to achieve this without modifying every single ...

Angular2 Cascading Animations

I have been working on implementing cascaded animations for a list of elements. Although I successfully applied the state triggers, following the guidelines in the documentation, I am encountering an issue where all element states are being applied simult ...

TypeScript allows for the declaration of a function that includes a mandatory property within the function signature

If I desire a tagged function with an interface such as: interface TaggedFun { (args): void; tag: boolean; } It appears that declaring a function to match this signature is not possible (since any function literal will lack the mandatory tag prop ...

Unable to use 'ngFor' as it is not recognized as a property of ... in a mixed AngularJS and Angular environment

My AngularJS and Angular hybrid application is giving me trouble when I try to downgrade my Angular test.component. Every time I attempt it, I encounter the following error messages: Can't bind to 'ngFor' since it isn't a known pro ...

How to display specific JSON objects that meet particular criteria in HTML cards using Ionic and Angular?

As a beginner in Ionic/Angular, I am attempting to fetch data from a JSON file and display it using cards in the HTML. The JSON contains numerous objects that are either marked as "deTurno == true" or "deTurno == false". Here is what I have so far: publi ...

Is it possible to incorporate websockets into an Angular Universal 9 app using express-ws and the WebSocket client API?

I am completely puzzled by the behavior I am experiencing, so I have decided to share the Angular Universal server code that is powering my express server. I suspect that there might be something in Angular Universal's rendering engine causing issues ...

React refs should always be validated for null or never values to avoid any potential issues

As I set up a react ref to be used in useEffect, the compiler is throwing an error stating that myRef.current evaluates to never: import React, {useRef, useState} from 'react' export default function RefProblem() { const myRef = useRef(null ...

Angular 2/NPM: setting up a new directory with all the necessary files for running the application

I'm feeling a bit frustrated, but I'm giving it a shot anyway. Our goal is to create a TypeScript Angular 2 hello world app that we can use as the front end for a Spring app. Currently, we're using the Angular 2 quickstart as our foundation ...

Generate a compressed file in RAM and then save it to Amazon S3

I'm currently working on a project where I need to compress text data into a zip file in memory using TypeScript and then upload it to an AWS S3 bucket. The input data is in plain text CSV format. However, I seem to be encountering an issue where the ...

How can I send a parameter to a function and retrieve it upon clicking in Angular?

app.component.ts import { Component } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { title = & ...