MediaPlugin onStatusUpdate don't update data in view


#1

Hallo, I have in my view:
A player with play and stop icon:

<ion-icon name="play" *ngIf="!audio.play"></ion-icon>	
<ion-icon name="square" *ngIf="audio.play"></ion-icon>

when audio finish i need to switch icon, and i did:

this.audio.play = false;
this.fileAudioCommento = this.media.create('path/to/file.mp3', onStatusUpdate, onSuccess, onError);          
this.fileAudioCommento.play();
this.audio.play = true;

const onStatusUpdate = (status) => {
            console.log(status);
            if (status == 4) {
                       console.log(this.audio.play);   //  true
                       this.audio.play = false;
                       console.log(this.audio.play);   //  false 
            }
}

but in view audio.play is true.
How can I solve?

global packages:

@ionic/cli-utils : 1.1.2
Cordova CLI      : 7.0.1 
Ionic CLI        : 3.1.2

local packages:

@ionic/app-scripts              : 1.3.7
@ionic/cli-plugin-cordova       : 1.1.2
@ionic/cli-plugin-ionic-angular : 1.1.2
Ionic Framework                 : ionic-angular 3.2.0

System:

Node       : v6.10.3
OS         : macOS Sierra
Xcode      : Xcode 8.3.2 Build version 8E2002 
ios-deploy : 1.9.0 
ios-sim    : 5.0.13 

Thank you so much


#2

Does the code actually trigger? Are the console.log firing?


#3

Yes in javascript all works and the console.log print the value correctly.
Switching the value of this.audio.play with a button works too.
But in the html don’t change the value, it seems a data binding problem?

Thank you


#4

It might be a change detection problem. One thing you can try is injecting a ChangeDetectorRef in your constructor and calling its detectChanges() method at the end of your status change handler. If that works, I would argue this is an ionic-native bug.


#5

Yes! It works.
Thank you!


#6

@ihadeed: Is this something that is possible for the ionic-native shim to do for us, or is it something that must be done in app code?

Also reported as ionic-native #1591.


#7

@rapropos

This is happening because we’re just passing the callback as-is to the plugin, we’re not converting it to a promise/observable. It’s possible to fix it, but I think it’s better to have less Angular specific code in Ionic Native. I recommend wrapping it with ngZone.run(() => { … }) manually.


#8

Wow. OK, I’ll defer to your opinion here, but I have always felt that 90% of the benefit of using ionic-native is that it Angularizes everything for me. I feel really uncomfortable both ever manually dealing with zones myself or recommending that others do so, but I guess I’ll have to change my tune on that. Thanks for taking the time to respond.


#9

@rapropos

On a second thought…

We can solve this issue without adding Angular specific code in Ionic Native (ngZone.run() … etc).

We can change the definitions of the Media plugin to work as follows:

let file: MediaObject = this.media.create('file.mp3');
file.onSuccess().subscribe(() => { ... }); // replaces onSuccessCallback
file.onError().subscribe(() => { ... }); // replaces the onErrorCallback
file.onStatusUpdate().subscribe(() => { ... }); // replaces onStatusUpdate

This means that the .create() function will no longer take the callbacks as parameters. Ionic Native will create those callbacks and converts them into Observables since they emit data more than once. I can probably do this in a way that doesn’t break old apps… (the backwards compatibility will be removed in Ionic Native 4.x)