View not updating in Ionic 2

I’m using cordova-plugin-file-transfer to download a file. I’m getting the progress of the download using progressEvent. All works well, the console shows the percentage updates, except… my view isn’t updating. {{percentage}} isn’t updated. If I put it in the beginning of the download() function, it does update my view. Anyone who has an idea what’s causing this, or knows how to fix it?

download() {
    this.setpercentage(50); <-- works
    this.fileTransfer.download(
        this.uri,
        'cdvfile://localhost/persistent/path/to/downloads/test.mp4',
        function (entry) {
            console.log("download complete: " + entry.toURL());
        },
        function (error) {
            console.log("download error source " + error.source);
            console.log("download error target " + error.target);
            console.log("download error code" + error.code);
        },
        false,
        {
            headers: {
                "Authorization": "Basic dGVzdHVzZXJuYW1lOnRlc3RwYXNzd29yZA=="
            }
        }
    );

    var self = this; // store outer this in a variable
    this.fileTransfer.onprogress = function (progressEvent) {
        if (progressEvent.lengthComputable) {
            console.log((progressEvent.loaded / progressEvent.total));  <-- works great
            self.setpercentage((progressEvent.loaded / progressEvent.total), self); // <-- doesn't work
        } else {
        }
    }
}

setpercentage(perc, self) {
    console.log(perc); <-- works
    self.percentage = perc; <-- doesn't work
}

Probably a situation where you have to manually trigger change detection. Try injecting a ChangeDetectorRef and calling its detectChanges() method after you’ve modified the percentage property of your controller.

Cool! It’s working now! Thanks!!!
Any idea why detectChanges() is needed here?

Probably because the progress listener is running outside of the Angular zone. This is normally the sort of thing that ionic-native takes care of, but either you’re not using it or it isn’t doing so in this case (which I would consider a bug).

1 Like

I installed the plugin manually, so I’m not using ionic-native. Thanks for the advice!

I’ve followed your advice and I’m using ionic-native now. Everything works fine, except for the progress-part. When I try to build to project, it says: Property 'lengthComputable' does not exist on type '(event: ProgressEvent) => any. Same for loaded and total.

Couldn’t find anything in the docs about implementing onProgress the right way… Here’s my code:

downloadnative()
{
        console.log("downloadnative");
        this.fileTransfer.download('...', '...').then((entry) => {
            console.log('download complete: ' + entry.toURL());
        }, (error) => {
            console.log('error');
        });
        this.fileTransfer.onProgress = function (progressEvent) {
            if (progressEvent.lengthComputable) {
                console.log((progressEvent.loaded / progressEvent.total)); 
                this.setpercentage((progressEvent.loaded / progressEvent.total) * 100);  
            } else {
            }
        }
    }

What does progressEvent actually look like?

Thanks for your reply! That’s probably where I’m stuck. How can I “see” what progressEvent looks like? I’ve tried console.log(progressEvent); but that didn’t show a thing on the console.

I’m not sure if this will solve your problem, but it looks like in Ionic Native you’d implement the progress handler like so:

this.fileTransfer.onProgress(progressEvent => {
    if (progressEvent.lengthComputable) {
        console.log((progressEvent.loaded / progressEvent.total)); 
        this.setpercentage((progressEvent.loaded / progressEvent.total) * 100);  
    } else {
    }
});

In the original plugin you overwrote the function like you were doing, but in Ionic Native you pass the handler.

3 Likes

Works like a charm! Thanks!