"Troubleshooting: Why Angular2's ngOnChanges is not triggering with array input

I am currently using a ParentComponent to pass inputs to a ChildComponent. When the input is a number, the ngOnChanges hook successfully fires. However, when it's an array, the hook does not trigger.

Could someone help me identify what I might be doing incorrectly, or provide guidance on how to ensure ngOnChanges fires when the array is modified?

Thank you.

child ts:

export class ChildComponent implements OnInit {
  @Input() num = 0;
  @Input() arr: Array<string> = [];
  constructor() { }

  ngOnInit(): void {
  }

  ngOnChanges() {
    console.log('input changed');
  }

}

parent ts:

export class ParentComponent implements OnInit {

  constructor() { }
  num = 0;
  arr : Array<string> =[];

  ngOnInit(): void {
  }

  changeNumber() {
    this.num = this.num + 1;
  }
  changeArray() {
    this.arr.push('some value');
  }

}

parent html:

<button (click)="changeNumber()">change num</button>
<button (click)="changeArray()">change array</button>
<app-child [num]="num" [arr]="arr"></app-child>

Answer №1

The difference lies in the fact that `num` is considered a primitive data type, while an array is treated as an object. An array functions as an object where the variable `arr` stores the reference. When you add a new element to the array using "push," the reference itself remains unchanged.

This is precisely why the function `ngOnChange` does not trigger. To create a new reference for the array and add a value to it, you can utilize the following code:

this.arr = [...this.arr, 'new value'];

Answer №2

When it comes to detecting changes in arrays, ngOnChanges falls short as it only monitors changes in the array reference itself, not its content. To work around this limitation, you can utilize a setter method.

  private _arr: Array<string> = [];
  @Input() set arr(data) {
    this._arr= data;
    console.log(this._arr);
  };

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

An issue arises when trying to group and sum an array of objects due to difficulty converting strings to arrays in TypeScript

Below is the provided code snippet: Definition of Interface - interface IWEXInterface { readonly Date?: string; "Exec Qty"?: string; readonly Expiry?: string; } Data Collection - let data: IWEXInterface[] = [ { Date: &qu ...

"Using RxJS to create an observable that filters and splits a string using

I need to break down a string using commas as separators into an observable for an autocomplete feature. The string looks something like this: nom_commune = Ambarès,ambares,Ambares,ambarès My goal is to extract the first value from the string: Ambarès ...

I tried implementing enums in my Angular Material select component, but unfortunately, it seems to be malfunctioning

Here is my TypeScript file I am working on creating a select list with enums in my project, but I am encountering an error. I have shared screenshots showing the enums with both keys and values, but I only want to display their keys and save their values ...

What steps should I take to set up an automated polling system for real-time data updates in Angular?

Hello everyone, I am currently delving into the world of Angular and facing a challenge with refreshing service data automatically by making API requests at regular intervals. The focus is on a particular service where I aim to update the shopPreferences f ...

Having trouble dispatching a TypeScript action in a class-based component

I recently switched to using this boilerplate for my react project with TypeScript. I'm facing difficulty in configuring the correct type of actions as it was easier when I was working with JavaScript. Now, being new to TypeScript, I am struggling to ...

To set up the store in configureStore, you must provide one type argument for the 'MakeStore' generic type

Encountering an issue with MakeStore showing a Generic type error 'MakeStore' requires 1 type argument(s) .ts(2314) Here is the code from configureStore.ts: import { configureStore, EnhancedStore, getDefaultMiddleware, } from '@reduxj ...

Utilizing the Injector for Quality Testing Services

After bootstrapping my service before its dependency, I rely on the Injector to handle the dependency once it's ready. constructor(private readonly injector: Injector) { const interval = setInterval(() => { const myService = injector.get(MyS ...

Angular issue: Readonly or disabled input fields not submitting data

Struggling with creating a form in Angular 2 to submit dynamically generated values from a service. The goal is to calculate the equivalent amount of bitcoin for X chilean pesos using Angular's http module to fetch the price. However, facing an issue ...

Ideal method of re-entering ngZone following an EventEmitter event

There is a specific component that wraps around a library, and to prevent the chaos of change detection caused by event listeners in this library, the library is kept outside the Angular zone: @Component({ ... }) export class TestComponent { @Output() ...

Access the CSV file using Office365 Excel via a scripting tool

Objective I want to open a CSV file using Office365's Excel without actually saving the file on the client's machine. Challenge The issue with saving raw data on the client's machine is that it leads to clutter with old Excel files accumu ...

Retrieve the observable value and store it in a variable within my Angular 13 component

Incorporating Angular 13, my service contains the following observable: private _user = new BehaviorSubject<ApplicationUser | null>(null); user$ = this._user.asObservable(); The ApplicationUser model is defined as: export interface ...

Webpack magic comments are not supported by dynamic import in Angular 8.0

After upgrading from Angular 7 to Angular 8, I observed a downgrade in my webpack version from 4.33.0 to 4.30.0. With the new support for dynamic importing in angular8, I wanted to utilize webpack "magic comments" to customize the chunk name of my angula ...

"Exploring the world of Typescript's return statements and the

I'm currently grappling with a design dilemma in typescript. Within my controller, I perform a validation process that can either return a 422 response, which ends the thread, or a validated data object that needs to be utilized further. Here's a ...

The issue of "Undefined Index" arises when attempting to access

It's strange that I'm getting this error saying the variable doesn't exist in the array. But when I double-check the array itself, it clearly shows that it does exist. Am I missing something here? Error Message: Undefined index: uuid on lin ...

Is there a way to manage specific HTML elements in Angular?

I am working on displaying a list of enable/disable buttons for different users. The goal is to show the appropriate button for each user based on their status - enabling if disabled and disabling if enabled. To achieve this, I have utilized the flags "use ...

Tips for neatly wrapping a class constructor

Currently, I am experimenting with code to create a more streamlined Angular Dialog initializer. This initializer should be passed a constructor function along with its arguments in a type-safe manner. The current implementation works, but it is challengi ...

There was an error encountered trying to access the options (URL) with a 405 method not allowed status. Additionally, the request to load the (URL) failed with a response indicating an

I attempted to retrieve data from an API using httpClient in Angular 5, but encountered errors. Below are the issues I faced: 1) ERROR: when trying to access http://localhost:8080/api/getdata, I received a 405 error (method not allowed). 2) ERROR: failed t ...

Using Typescript to pass an interface as an argument to a function that requires a JSON type

Here is an extension related to the topic of Typescript: interface that extends a JSON type Consider the following JSON type: type JSONValue = | string | number | boolean | null | JSONValue[] | {[key: string]: JSONValue} The goal is to inform type ...

Can an interface be designed to have the option of containing either one property or another?

I am in need of an interface that resembles the following structure: interface EitherOr { first: string; second: number; } However, I want to make sure that this interface can only have either the property first or second. Do you think achieving this ...

Enumeration in zod validation

Currently, I am using a schema in zod and have an object. const escortTypeOptions = [ { value: "Nutrition", label: "תזונה" }, { value: "Training", label: "אימונים" }, { value: "Nutrition ...