The issue arises with Angular's input property not recognizing changes when a new item is added to an array

I am currently working with an array called dataSource in my Angular project. I need to detect and handle any changes that occur when new items are added or deleted from this array. To do this, I have passed the array as a getter setter for @Input change detection in a child component.

Below is my AppComponent :

<div>
    <vertital-tabs
          [config]="config"
          [dataSource]="dataSource"    <-- Need to detect Array changes in Child
          [(selectedItem)]="selectedItem">
    </vertital-tabs>

    <div style="background-color: yellow;margin: 10px">
        {{ selectedItem | json }}
     </div>
</div>

In the ChildComponent (vertical-tabs) :

get dataSource(): any {
        return this._dataSource;
}

@Input() set dataSource(value: any) {
    this._dataSource = value;
    // The setter is not triggered when adding a new item to the array.
    // I want it to trigger on clicking the Add New Item button....
    debugger;
}

The current issue I am facing is that the setter method is not being called when a new item is added to the array. However, it does work correctly when deleting an item.

Note: Due to having numerous properties as inputs in real scenarios, using ngOnChanges() is not feasible.

Here is a sample implementation I created for reference: https://stackblitz.com/edit/angular-vertical-tabs-component-split-yzynef

Answer №1

Angular only monitors changes in the reference - if the reference remains the same, the setter will not be triggered.

In app.component.ts:

let nextItem = this.dataSource.length;
this.dataSource.push({
  id: nextItem.toString(),
  text: 'item ' + nextItem.toString(),
  icon: 'settings',
});

Instead of creating a new array and assigning it to dataSource, you are adding an item to the existing array here.

In vertical-tabs.ts:

onDelete(item, index) {
  this.dataSource = this.dataSource.filter((x) => x !== item);
}

This code snippet creates a new array and assigns it to dataSource.

Deletion works as expected because a new array is generated, but addition does not. To resolve the issue, make a copy of the array and assign it to dataSource:

let nextItem = this.dataSource.length;
this.dataSource = [
  ...dataSource,
  {
    id: nextItem.toString(),
    text: 'item ' + nextItem.toString(),
    icon: 'settings',
  }
];

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

The type '{ children: Element; }' cannot be assigned to the type 'IntrinsicAttributes & ReactNode'

Encountered this error: Type '{ children: Element; }' is not assignable to type 'IntrinsicAttributes & ReactNode'. export const withAppProvider = (Component: AppComponent) => { return function WrapperComponent(props: any) { ...

Tips for dealing with Uncaught Error: [nuxt] store/index.js must have a function that returns a Vuex instance

In my Nuxt project, I have set up a default store in Nuxt within the store/index.js file as per the guidelines provided in the documentation. However, upon trying to render my app, I encounter the following error: Uncaught Error: [nuxt] store/index.js sh ...

The HTML return function failed to execute properly when I included the return false statement

Having an issue with submitting the username and email to a file named welcome.php. It was functioning properly until I added a return false statement to prevent registration errors. Despite meeting all the requirements I've specified, it's not r ...

Error encountered while attempting to import a virtual module, import resolution unsuccessful

I've been working on creating type declarations for a Javascript module in Typescript. My goal is to define interfaces using what I believe is a virtual module. Initially, I had no trouble defining the base module types. However, when attempting to im ...

Is it necessary to include index.js in each component in a react project?

After checking out an article on the benefits of using a Folder Components structure, I came across this link. The author praised the use of index.js as a solution, but there was also a comment from someone arguing that it's unnecessary to have index. ...

Concerning the issue of components not loading correctly when using Angular with Lazy Loading Routing

Encountering an unusual issue while utilizing lazyload routing in our application! Within AppModule, there is TopModule followed by DashboardModule, all being loaded lazily. When localhost:4200/dashboard is accessed, the loading sequence is AppModule, To ...

md-select is failing to properly connect with the object assigned to ng-model

I am struggling to bind some md-select dropdowns with a scope object in my angular controller. Here is how the html looks like: <div id="horizontal_form_category" class="row"> <div class="col-md-2 col-lg-2" data-ng ...

Looking to create a timepicker in ReactJS similar to the Uber timepicker, with the added feature of a "Now"

https://i.sstatic.net/wxY1O.jpg {val.getDate() === +todayDate ? ( <TimePicker className="carDetailOption" value={val} onChange={(date) => setVal(date)} ...

What is the best way to display JSON data in a Listview control?

What is the best way to display JSON data in a list format? Currently, I am able to retrieve JSON data and display it in an alert dialog. The JSON data looks like this: [{"_id":"5449f20d88da65bb79a006e1","name":"name3","phone":"888888","service":"service ...

Executing a function with a click, then undoing it with a second click

My goal is to trigger an animation that involves text sliding off the screen only when the burger icon is clicked, rather than loading immediately upon refreshing the page. The desired behavior includes activating the function on the initial click and then ...

Attempting to start the server with http-server resulted in a TypeError indicating that Readable.from is not a valid function available

I am currently integrating PWA into my new Angular project. C:\Users\alan_yu\angular-pwa>http-server -p 8080 -c-1 dist/angular-pwa Initializing http-server to serve the files in dist/angular-pwa http-server version: 14.0.0 http-server ...

I am facing issues with Firebase functions where the parameters received from Express.js routes are

I am encountering an issue while trying to use firebase functions to host my expressjs webapp. For some reason, all get parameters appear to be undefined. Can anyone help me figure out what the problem might be? import functions= require("firebase-fun ...

Issue with combining jQuery-UI and Bootstrap offcanvas components

I've been struggling to understand why my Bootstrap navbar isn't working properly with jQuery-UI. It seems like they're not cooperating, and I can't seem to figure out the issue. If you have any insight into this problem, you'll be ...

How can data tables be generated using AJAX, JSON, HTML, and JS?

HTML: <table> <tr> <th>Student Name</th> <th>Student Grades</th> </tr> <tr> <td> <select name="dropdown" id= ...

Sending information from one ajax request to anotherORTransferring

Apologies for not including code in this post as I am currently working on a project in a car without internet access. Thankfully, I am using the amazing Stack Exchange app. Currently, I am facing a challenge where I need to work with two separate API cal ...

Navigating through stacks in React Native

My stack navigation was working perfectly at first, but now it seems to have stopped functioning :( npm install --save react-navigation npm install --save react-native-gesture-handler react-native link npm install When I run the commands above, I am enco ...

Navigating arrays and objects in JavaScript: A beginner's guide

let dataPoints = [{ x: 75, y: 25},{ x: 75+0.0046, y: 25}]; What is the best way to loop through this array of points and print out each x and y value sequentially? ...

Feeling lost with the concept of getcontext in js/ts and uncertain about how to navigate through it

Recently, I've been encountering undefined errors in my browser and can't seem to figure out how to resolve them. It seems that the usage of the keyword "this" in JavaScript and even TypeScript is causing quite a bit of confusion for me. Let&apo ...

Click on the div and any elements it contains in the CSS and JavaScript

I want to create a partially transparent overlay that covers an entire web page, similar to the example here: <div id="overlaySplash" onclick="clickHandler(this)"> <div id="insideBox"> [ insert clickable elements here with onclick="dos ...

Node C++ Addon Typescript declaration file

I have developed a Node C++ Addon that wraps a class similar to the one outlined in the official Node documentation. By using require(), I am able to access my addon and retrieve the constructor for my class in order to instantiate it. const { MyClass } = ...