Ionic-framework: [ionic2] virtualTrackBy seem to not be working

Created on 3 Aug 2016  路  16Comments  路  Source: ionic-team/ionic-framework

I was looking for some optimisation in my app then i stumble uppon something weird. In my template i've done this:

<ion-content>
    <ion-list [virtualScroll]="storeStands.collection$ | async"
        [virtualTrackBy]="trackStand"
        [headerFn]="alphabetical" >
        <ion-item-divider *virtualHeader="let header">{{ header }}</ion-item-divider>
        <a ion-item text-wrap
            *virtualItem="let stand"
            [navPush]="[standPage, { stand: stand }]">
            <h2>{{ stand.organization }}</h2>
        </a>
    </ion-list>
</ion-content>

In my controller

trackStand(index, stand: Stand) {
    console.log(index, stand);
    return stand.id;
}

Putting a console log in trackStand function but it's never called (as opposed with ngForTrackBy).

Explorating futher i put a console.log(val) inside the ionic-angular/components/virtual-scroll/virtual-scroll.js:305 to see if my parameter was listened, and i get undefined.

    set: function (val) {
        this._trackBy = val;
    }

Moving back to my template i set [virtualTrackBy]="'trackStand'" and i then get 'trackStand' inside virtual-scroll.js:306.

But was more curious an tracked where this._trackBy was used, in the same file virtual-scroll.js:260 inside a condition.

set: function (val) {
    this._records = val;
    if (util_1.isBlank(this._differ) && util_1.isPresent(val)) {
        this._differ = this._iterableDiffers.find(val).create(this._cd, this._trackBy);
    }
}

I put console.log(this._trackBy, this._differ) inside that condition and surprise, this._trackBy is undefined and this._differ has a method _trackByFn with attribute name: 'trackByIdentity'.

Putting the console.log just before the condition, the this._trackBy display two times, one with undefined and one with 'trackStand', this._differ doesn't change at all.

A final test was to remove the condition if (util_1.isBlank(this._differ) && util_1.isPresent(val)) and there this._differ._trackByFn.name was empty when [virtualTrackBy]="trackStand" and only there it work as expected.

So my conclusion is, when this._differ is set, and even if val change, this._differ isn't changed, and doesn't take in account this._trackBy.

Most helpful comment

Any update about this issue?
I have the same problem with ionic 2.0.0 RC4,
[virtualTrackBy]="trackStand" does not execute,
if (util_1.isBlank(this._differ) && util_1.isPresent(val)) condition it's alway false.

All 16 comments

Or maybe it's me who use it badly ?

Hello, thanks for opening an issue with us! Would you be able to provide a plunker that demonstrates this issue? Thanks for using Ionic!

+1

Any update about this issue?
I have the same problem with ionic 2.0.0 RC4,
[virtualTrackBy]="trackStand" does not execute,
if (util_1.isBlank(this._differ) && util_1.isPresent(val)) condition it's alway false.

I am also having this problem. I am using an ion-searchbar to filter down my ion-list but when there are hundreds of records that get regenerated, the phone runs very poorly.

Just came across this issue as well. Added virtualTrackBy with a console.log statement in the function it uses and it never gets called. Seems like virtualTrackBy is not working at all.

@jgw96 - this would be great to get fixed before 2.0 final as it is a function listed in the documentation , and an important function for list performance that just does not work currently.

I am also having the same problem, same as above, added a console.log in the function and nothing gets called.

Agreed, @ghenry22. Virtual scrolling is a must for big lists but DOM rewrites are too expensive to not have this functionality. A decent example in the Ionic docs would be very useful. Interestingly, if you go to:
node_modules/ionic-angular/components/virtual-scroll/virtual-scroll.js, there is no Object.defineProperty(VirtualScroll.prototype, "virtualTrackBy", {}) as with headerFn and footerFn and as one might expect.

@jgw96 - is it too late for this issue? It would be great if this could be slipped into final.

Just upgraded to 2.0.0, was excited to try virtualScroll in place of ngFor, but virtualTrackBy is never called.

I don't know if it work for anyone yet, but it work normal for me .
Here is the html

<ion-content padding>
  <ion-list [virtualScroll]="noidungs | async" no-lines [virtualTrackBy]="identify">
    <div *virtualItem="let nd" style="width: 100%">
      <ion-card>
        <ion-card-header>
          {{nd.name}}
        </ion-card-header>

        <ion-card-content>
          {{nd.message}}
        </ion-card-content>
      </ion-card>
      <div style="height:10px"></div>
    </div>
  </ion-list>
</ion-content>

And here is controller

import { Component } from '@angular/core';
import { NavController, NavParams } from 'ionic-angular';
import { NoiDungService } from '../../shared/noi-dung.service';

@Component({
  selector: 'page-list',
  templateUrl: 'list.html'
})
export class ListPage {

  private noidungs;

  constructor(public navCtrl: NavController,
    public navParams: NavParams,
    private noiDungService: NoiDungService) { }

  ionViewDidLoad() {
    console.log('ionViewDidLoad ListPage');
    this.getNoidungs();
  }

  public getNoidungs() {
    this.noidungs = this.noiDungService.getDataFromServer();
  }

  public identify(index, item) {
    console.log('helo world');
    return item.name;
  }

}

Here is the output of ionic info

Cordova CLI: 6.4.0 
Ionic CLI Version: 2.2.1
Ionic App Lib Version: 2.2.0
ios-deploy version: Not installed
ios-sim version: Not installed
OS: Linux 3.16
Node Version: v6.9.1
Xcode version: Not installed

Hope that help :smile:

If you add a console.log statement in your method that virtualtrackby is supposed to call you will see that it never gets called. The list will still display and all looks normal but the track by function is not used so you don't get the benefits of it.

@ghenry22 yes i know, but in my code the console.log('helo world') is run, so the identify is called by virtualTrackBy

Any updates?

Fixed by @masimplo!!

Thanks for the issue! This issue is being locked to prevent comments that are not relevant to the original issue. If this is still an issue with the latest version of Ionic, please create a new issue and ensure the template is fully filled out.

Was this page helpful?
0 / 5 - 0 ratings