Black Sheep
Black Sheep

Reputation: 6694

Ionic - Onesignal - On handleNotificationReceived doesn't update view

I tried to update an array after received a notification from Onesignal like so:

getMsg.ts:

getMsg = Array<Object> = [];
...
constructor( ... private oneSignal: OneSignal ... ) {
...

    this.oneSignal.handleNotificationReceived().subscribe( () => {

        this.getMessage();
        console.log('handleNotificationReceived');                
    } );
}

getMessage () {

    this.getMsg.push( { text: 'some text' } );

    console.log( 'getMessage' );

    // Push is working
    console.log( JSON.stringify( this.getMsg ) ); // [{"text":"some text"}]
} 

getMsg.html:

...
<ion-list *ngFor="let m of getMsg">
    <ion-item>
        <p>{{ m.text }}</p>            
    </ion-item>
</ion-list>
...

But it doesn't work as expected.

I have an <textarea> in my getMsg.html file, when I type in it, the view magically updates (after I receive a notification).

And obviously, if I use the function getMessage() directly, it works.

What I tried too, is to update/reload the view with:

this.navCtrl.setRoot( this.navCtrl.getActive().component );

but with no luck.

Ionic: v3.4.0
Cordova: v7.0.1

Upvotes: 2

Views: 615

Answers (1)

Black Sheep
Black Sheep

Reputation: 6694

After a few days of breaking my brain, I solve it with the help of the following site:

Angular 2 runs inside of its own special zone called NgZone. Running inside a zone allows one to detect when asynchronous tasks – things that can alter the internal state of an application, and therefore its views – start and finish. Since these asynchronous tasks are the only thing that are going to cause our views to change, by detecting when they are executed Angular 2 knows that a view may need to be updated.

Solution code:

// Import NgZone
import { Component, NgZone } from '@angular/core';

// We add it to the constructor
constructor( ... private zone: NgZone, private oneSignal: OneSignal ... ) {
...

    this.oneSignal.handleNotificationReceived().subscribe( () => {

        this.getMessage();
    } );
}

getMessage () {

    // And here we run "NgZone"
    this.zone.run( () => {

        this.getMsg.push( { text: 'some text' } );

    } );       
}

Upvotes: 3

Related Questions