Incorrect order in Angular2 NgFor within tree model when elements are removed and then added back

Currently experimenting with Angular 2 alpha version 44.

Working with a tree model that utilizes recursion for display purposes. Each group contains 'Criterions', 'Segments', and other 'Groups'. Elements can be added or deleted at any level of the tree.

Encountering a strange issue when removing elements and adding new ones on the same level. The new elements are getting assigned a higher position property, causing the array to sort incorrectly. Despite the console showing the correct order, the view displays the items where the previously removed elements were positioned.

Upon logging the new array in the console, it appears in the correct order. Also, if you delete and add all tree elements using the "SHOW/HIDE" button, the view then displays in the proper sequence.

To observe this behavior firsthand and gain better understanding, please visit: Plunker link here:

  1. Remove the first element
  2. Add a new element
  3. Notice that the view's order does not match the console log
  4. Click the "SHOW/HIDE" button twice
  5. The view should now correctly display the order of elements

Is there an equivalent to ng1's trackBy functionality for ng2's NgFor? I couldn't find any reference to it within the sources.

Answer №1

trackBy functionality was introduced in version 2.0.0-beta.3

To learn more, check out this GitHub issue

Using a template element:

@Component(
  template: `
   <template ngFor let-item [ngForOf]="items" [ngForTrackBy]=customTrackBy">
      {{item}}
   </template>
   `
)
class MyComponent {
  customTrackBy(index: number, obj: any): any {
    return index;
  }
}

Utilizing *ngFor directive:

@Component(
  template: `
   <div *ngFor="let item of items; trackBy:customTrackBy">
      {{item}}
   </div>
   `
)
class MyComponent {
  customTrackBy(index: number, obj: any): any {
    return index;
  }
}

Check out another related issue on GitHub here

You have the choice to use either *

*ngFor="let character of characters | async" *ngForTrackBy="customTrackBy"

or simply

*ngFor="let character of characters | async ; trackBy:customTrackBy"

For further information, take a look at Angular 2 ngModel bind in nested ngFor

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

Sending numerous messages from a single event using Socket.io

After an exhaustive search, I have yet to find a solution to my problem. I am attempting to send a message from the server every time it detects a file change in a specific directory. However, instead of sending just one message, it sends the same message ...

Incorporating script within an ASPX webpage

I've been struggling with using this code on an ASPX page. I keep trying to implement it within a text box on the same page, but without success. Strangely though, I can successfully use the script within a text box in my master page. Any assistance w ...

utilizing vueJS for global notifications

It may sound like a cliché question, but I still haven't grasped it. I have a primary component that is always loaded in the application. Let's refer to it as DefaultContainer.vue <template> <div class="app"> .... Notifi ...

Develop a versatile factory using Typescript

For my current project, I am developing a small model system. I want to allow users of the library to define their own model for the API. When querying the server, the API should return instances of the user's model. // Library Code interface Instanc ...

Is there a way to direct to a specific URL upon clicking a button using PHP?

In my PHP code called registerprocess.php, it executes after clicking a submit button on another page named userregistration.php. If a user tries to register with an email that already exists in the database, I want registerprocess.php to redirect back to ...

Having issues with TableExport.js exporting Bootstrap HTML tables

I've been trying to use the TableExport.js plugin found at to add Bootstrap HTML table export functionality to my website. I meticulously followed all the steps to include jquery FileSaver, tableExport javascripts, and css. <!-- jQuery --> &l ...

How can I make one object's position target another grouped object in three.js, while still enabling rotation to track a camera in augmented reality?

Currently, I am utilizing a cutting-edge augmented reality library that specializes in advanced image tracking capabilities. Despite extensively studying this project, I have reached a point where I require assistance. Essentially, the library generates an ...

Implementing an extended interface as an argument in a function

Here is the code snippet for analysis: interface IUserData { FirstName: string, LastName: string, Email: string, Password: string } interface IState extends IUserData { isSuccess: boolean } const state: IState = { FirstName: &apo ...

What strategies can be used to address inconsistencies between the type system and runtime behavior?

I have created a unique TypeScript type called Awaitable<T> with the goal of ensuring that Awaited<Awaitable<T>> is always equal to T. export type Awaitable<T> = | (T extends Record<'then', Function> ? never : T) ...

Firebase causing API to render only upon typing initiation

I have been working on developing a Twitter-like app using React and Firebase, but I have come across a small bug. Currently, I am using useEffect to display my firebase collection when the page loads, and then mapping the tweets to the page. However, the ...

Custom cellRenderer prevents Ag Grid's autoHeight and wrapText features from functioning properly

I've been attempting to adjust the formatting of a long cell value by wrapping the text. According to the documentation, setting autoHeight=true and wrapText=true works fine without any cellRenderer components. However, when using a cellRendererFramew ...

The parameter of type 'never' cannot be assigned with the argument of type 'number | boolean | undefined'

In my project, I am creating a validation input using TypeScript in Next.js. interface InputRules { required?: boolean min?: number max?: number minLength?: number maxLength?: number } I have defined an object that contains methods to handle val ...

Preventing Context Menu from Appearing on Long Click in HTML5 Games

I'm attempting to utilize a similar technique as demonstrated in this stackoverflow post: How to disable the 'save image as' popup for smartphones for <input> However, I am encountering an issue where my button is not displaying at ...

The Chart.js donut chart is not displaying as expected on the HTML page when using

My HTML code is set up to display a donut chart with database records retrieved through a PHP script. The data is successfully fetched and visible in the browser console, but the chart itself is not showing up. How can I resolve this issue? console.lo ...

Tips for transferring large data without a page redirect using jQuery's post method:

Seeking advice on how to send large data via jQuery POST without redirecting the page. I'm working on a mobile chat project where communication between user app and server is done using JSON. The issue arises when dealing with big data as the jsonGet ...

Optimizing the performance of "document.createElement"

When attempting to display multiple rows of data in a popup using a for loop, I initially utilized text strings to create and append the div elements. However, I discovered that using document.createElement resulted in a 20% improvement in performance. D ...

Angular2 - HTML not displaying the response

I am currently mastering angularjs2. In my latest project, I attempted to fetch data from an API and received a response successfully. However, I encountered an issue where the response is not rendering in homepage.component.html as expected. I am unsure o ...

JS selection-dropbox

As someone who is relatively new to JS, I am struggling a bit. The goal of the code is to display items with specific content (ALL, A, B, C). While the code works fine with buttons, I can't seem to get it to work with a 'Dropdown-select', ...

What are the steps for utilizing the useReducer Hook with TypeScript?

I have successfully converted a React app to Typescript, but I am facing an issue with the useReducer Hook. The error message I'm getting is preventing me from moving forward. I have attempted different approaches to passing TypeScript interfaces in ...

The Node.js azure-storage TableService does not offer any functionalities or operations

Having trouble connecting to my Azure storage account due to issues with the azure-storage module. Specifically, after creating a TableService object, I am only able to access the filter method on it. When attempting to use methods like queryTables and cre ...