[SOLVED] DOM is not updating when I change the array that is binded to an ngFor

Hello,

I’m building an app using Ionic 2 alpha 53, Angular 2, Typescript…

What I have is similar to the example below:

HTML
<ion-item *ngFor="#item in items"> ... </ion-item>

TypeScript
export class MyPage { constructor() { this.items = []; // Create a blank array to avoid start-up errors MyProvider.getItems().then( items => { this.items = items; // Update items }); } }

After the page is loaded and it successfully retrieved the items from my provider, it does not update the DOM. I would have to manually click on something such as an Action Sheet or a Side Menu to refresh the DOM and display the updated items.

Not sure why I’m having this issue… I looked at the sample Ionic Conference App and it seems like they’re doing it exactly the same way.

Any thoughts?

EDIT: It seems like this issue only occurs when I try to replace the whole array. If I .push() or .splice() it updates fine. But again, Ionic Conference App is replacing the whole array and it works fine!

Assuming that you are using Http in angular2/http in your MyProvider class, use .subscribe instead of .then.

I guess this is a bug of Angular 2 because I have a similar problem for image. The image will not be shown after I pick it from the photolibary until I scroll my page or click a button.

That means anything inside a callback or a promise doesn’t work well for some reasons.

But this will work:

 setTimeout( () => {
     // update your data 
 },500)

Don’t know the difference between timeout callback and the provider callback. In my case, I’m using cordova image picker or camera plugin.

What about the provider is not a $http call?

$http no longer exists in Angular 2 so I assume you mean Http.

Using the example here “MyProvider.getItems()”, it totally depends on what getItems function is returning. In Angular 2 using the Http service returns something called an Observable which is part of the new RxJs library.

http://chariotsolutions.com/blog/post/angular2-observables-http-separating-services-components/

Thanks for your input …

My provider isn’t using HTTP…

I’m using PouchDB to store my data.

The function looks somewhat like this:

getItems(id){ return this.myDB.get(id).then(function(res){ return res; }); }

Which is similar to how Ionic did it in their conference app as well…

    return this.load().then(data => {
      return data.speakers.sort((a, b) => {
        let aName = a.name.split(' ').pop();
        let bName = b.name.split(' ').pop();
        return aName.localeCompare(bName);
      });
    });
  }`


Provider: https://github.com/driftyco/ionic-conference-app/blob/master/app/providers/conference-data.js
The page that's displaying the information: https://github.com/driftyco/ionic-conference-app/blob/master/app/pages/speaker-list/speaker-list.js

I tried wrapping the whole function with a timeout, and also tried wrapping the .then() portion with a timeout … no results :frowning:

Unfortunately, I’m not familiar with PouchDB. However, I can tell you that the reason they can call this.load().then is because they are returning a Promise object from the load function. Try this:

getItems(id){
    return new Promise(resolve => {
        this.myDB.get(id).then(items => resolve(items));
    });
}

Thanks!

It works fine now.

It’s strange though, the .then() was firing off before and console logging stuff for me. And if I click anywhere it actually updates the DOM. However, after wrapping my provider function with a promise it updates the DOM once it gets the data for me.

Thanks again.

1 Like