Search code examples
nativescriptangular2-nativescriptnativescript-angularnativescript-telerik-ui

RadListView cannot read property 'picture' of undefined (Android)


I am using RadListView and have a list of images that is using loadOnDemand to load more. Every once in a while I receive a nasty error on Android that says Cannot read property 'picture' of undefined, and it will sort of freeze the whole app for a little while.

It's frustrating because I keep thinking I fix it when it doesn't happen for a while, but then it will come back randomly. I thought a complete project refactoring might fix the problem, but it didn't.

I created a sample project that has the problem. https://github.com/keerl/radlistview-bug.

I also created a Playground for it: https://play.nativescript.org/?id=H7lJuH&template=play-ng&v=3

I also recorded a video of the problem happening. https://www.youtube.com/watch?v=_EGvw8REek8. The problem is very random, sometimes it will never trigger (which makes me think I fixed it), then randomly hours later start happening again. Only happens on Android. I've tried using plugins for image caching (WebImage) thinking that the image loading was causing the problem and maybe a placeholder would help, but that didn't fix it.


Solution

  • I have updated the playground for you. You were notifying too early to the list that notifyPullToRefreshFinished.

    You should only inform only when data is loaded. E.g.

    loadProducts(PullToRefreshInitiated: boolean) {
            return new Promise((resolve, reject) => {
                http.getJSON("https://randomuser.me/api/?results=25&inc=picture").then((r) => {
                    this.users$.push(r.results);
                    if (PullToRefreshInitiated) {
                        this.listView.notifyPullToRefreshFinished();
                    }
                    // Load a max of 50 items and then force a pull-to-refresh to get more data.
                    if (this.users$.length > 50) {
                        resolve(true);
                    }
                    else {
                        resolve(false);
                    }
                }, (e) => {
                    console.log(e)
                });
            });
        }
    

    P.S. Two more suggestions that I have personally implemented in a similar environment.

    1. Use image cache.
    2. Use *ngIf in e.g. <Image *ngIf="item" [src]="item.picture.medium"></Image>, you can use a Label for else block of you want.