[VIDEO] View not updating after the change in ngFor Array?

Each time I receive a notification I add it to an array and I display that array inside the view using ngFor.

So I have the view with notifications opened. I receive a notifications. Alert gets displayed, but changes in the “list” are not updated unless I touch the view.

This is really annoying. How can I solve it?

UPDATE #1

I added the video. As you can see, the list is not update until I touch the view with my finger. Even when 2 notifications arrive, unless I touch on the view, the list wont get update.

Any ideas?

https://vimeo.com/191212038

UPDATE #2

It’s probably a zone problem. Nobody can help without seeing code.

First, notification is received and the function saveNotificationToLocalStorage is called

// app.component.ts

OneSignal.handleNotificationReceived().subscribe((data) => {
        data.payload.rawPayload = JSON.parse(data.payload.rawPayload);
        this.user.saveNotificationToLocalStorage(data);
      });

// Function saveNotificationToLocalStorage … inside “providers/user-data.ts”

saveNotificationToLocalStorage(notification){
    var tmpNotification = notification.payload;
    var _isAppInFocus = notification.isAppInFocus;

    var tmpArr = JSON.parse(window.localStorage.getItem("arrayOfNotifs"));
    tmpArr.unshift(tmpNotification);
    window.localStorage.setItem("arrayOfNotifs", JSON.stringify(tmpArr));

    // Important part
    if(_isAppInFocus){
        this.events.publish('notifications:update', tmpArr);
    }
}

And then when event is fired “dashboard.ts”

listenToEvents(){
    this.events.subscribe('notifications:update', (notifications) => {
      this._notifications = notifications[0];
    });
  }

Dashboard.html

<ion-content no-margin no-padding>
  <ion-list no-margin no-padding [virtualScroll]="_notifications" approxItemHeight="40px">
    <ion-item-sliding #item *virtualItem="let notification" no-margin no-padding>
      <ion-item no-margin no-padding>
        {{ notification.title }}
      </ion-item>
      <ion-item-options side="right" no-margin no-padding>
        <button ion-button>
          <ion-icon ios="ios-archive" md="md-archive"></ion-icon>
          Save
        </button>
        <button ion-button color="danger">
          <ion-icon ios="ios-trash" md="md-trash"></ion-icon>
          Delete
        </button>
      </ion-item-options>
    </ion-item-sliding>
  </ion-list>
</ion-content>

I have seen @OneSignal posting in these forums, perhaps they can speak to whether that usage is going to get your saveNotificationToLocalStorage called in the right zone.

@thebasix @rapropos The issue doesn’t see to be with OneSignal since you are getting all the events in the list. Can you try setting inFocusDisplaying to none to see if it is a focus issue?

I set it like this OneSignal.inFocusDisplaying(OneSignal.OSInFocusDisplayOption.None); but still the issues persist. In my opinion, I too, dont think it is OneSignal issue.

This problem is a little bit similar to what happened to me here:

Possible workarounds could be:

listenToEvents(){
    let thisObj = this;
    this.events.subscribe('notifications:update', (notifications) => {
        thisObj._notifications = notifications[0];
    });
  }

Or this:

listenToEvents(){
    let thisObj = this;
    this.events.subscribe('notifications:update', function (notifications) {
        setTimeout (function () { thisObj._notifications = notifications[0]; }, 2000);
    });
  }

Or this:

listenToEvents(){
    let thisObj = this;
    this.events.subscribe('notifications:update', (notifications) => {
        setTimeout (function () { thisObj._notifications = notifications[0]; }, 2000);
    });
  }

@thebasix have you resolved the issue? If so, could you share the solution…

I have encountered a similar issue that the view is not updating (it’s just a simple string, not even an array) when the underlying data changes through receiving a Push Message. Code extracted as follows:

In the HTML:
Name {{nameValue}}
In the .ts file:
events.subscribe(‘refreshdata’, (data) => {
console.log(‘Data Received’, data);
this.nameValue = “HAHAHAHA”;
});
this event is fired in another place when a Push Message is received. And I can confirm the code got executed, as the console did print out “Data Received”. However, the label in the html code does not get updated, unless I switch to another tab and go back, or I click on an input field on that tab, that seems to then trigger the view to get updated.

Wherever that is would seem to be the source of the problem. Are you using ionic-native?

Yes, I am using ionic native, version 2.9.0

Can you see if the problem persists using the current version?

I have updated to the following, but still same issue…

$ ionic info

cli packages: (/Users/albertwong/myApp2/node_modules)

@ionic/cli-utils  : 1.10.2
ionic (Ionic CLI) : 3.10.3

global packages:

Cordova CLI : 7.0.1 

local packages:

@ionic/app-scripts : 2.1.4
Cordova Platforms  : android 6.2.3 android2 6.2.3 ios 4.4.0
Ionic Framework    : ionic-angular 3.6.1

System:

ios-deploy : 1.9.1 
Node       : v6.9.5
npm        : 4.1.2 
OS         : macOS Sierra
Xcode      : Xcode 8.3.3 Build version 8E3004b

Apologies, but this does not show that you have upgraded to the latest ionic-native shim for your push notifications. Things changed drastically in version 3.

Thanks, @rapropos.

I have finally found out the issue (I hope it’s the correct issue and the right way of doing it but it’s working now…):

It’s related to ionic zone. (You can read the explanation here: https://blog.thoughtram.io/angular/2016/02/01/zones-in-angular-2.html)

I have my function to update data code runs inside this.zone.run() and now it can refresh automatically:

events.subscribe('some event', (data) => {
  console.log("Call executed");
  this.zone.run(() => {
    this.getTask();  (this will pull data from database to get latest data when event got triggered)
  });
});
1 Like

It isn’t the right way of doing it. Ionic-native takes care of feeding you Promises and Observables that are zone-aware. App code should not be manually dealing with zones, ever.

Very late to the part but thank you for this.
I wasted most of the day trying to solve a similar issue, that I didn’t realise was related to push notifications.

so it has nothing to do with Ionic. Pure Angular. Angular’s Change detection is triggered by certain browser side events (click, mouseover, keyup, etc.), async stuff like setTimeout() setInterval() and ajax requests.

In your case whatever methods plugin (OneSIgnal) is using - those are not getting onto the radar of Angular.
So yes fixes are:

  1. Run a method inside Angular zone explicitly when such event occurs
  2. Or force change detection after data has changed (import ChangeDetectorRef and to cdr.detectChanges())