adriancarriger / angularfire2-offline

🔌 A simple wrapper for AngularFire2 to read and write to Firebase while offline, even after a complete refresh.
https://angularfire2-offline.firebaseapp.com/
MIT License
207 stars 48 forks source link

List subscription doesn't emit new value when updating a list #65

Open belavenuto opened 7 years ago

belavenuto commented 7 years ago

Hi, I don't know if I'm missing something, but I'm facing problems when subscribing to a list.

Every thing works fine when adding or removing items from a list, but when I update something inside the list, the subscription doesn't emit a new value. This is an example code:

export class HomePage {

  items: any[];

  constructor(private db: AngularFireOfflineDatabase) {}

  ionViewWillLoad() {
    this.db.list('items')
      .subscribe(data => { this.items = data });
  }

  doAdd() {
    this.db.list('items').push('some value');
  }

  doRemove(key: any) {
    this.db.object(`items/${ key}`).remove();
  }

  doUpdate(key: any) {
    this.db.object(`items/${ key}`).set('another value');
  }
}

And the template:

<ion-content padding>
  <ion-list>
    <ion-item *ngFor="let item of items">
      <h2>{{ item.$key }}</h2>
      <p>{{ item.$value }}</p>
    </ion-item>
    <button ion-button clear block (click)="doAdd()">Add</button>
    <button ion-button clear block (click)="doUpdate(items[0].$key)">Update</button>
    <button ion-button clear block (click)="doRemove(items[0].$key)">Remove</button>
  </ion-list>
</ion-content>

When I click Add or Remove, the list is updated correctly, but when i click Update, the value of first item is not updated to "another value", until I reload the page.

angularfire2-offline-list-issue

If I run the same code, but using AngularFireDatabase, it works as expected.

Thanks in advance!

matheus-fatguys commented 7 years ago

I'm facing the same problem. Did you solve it?

belavenuto commented 7 years ago

Actually, I've tried a (poor) workaround that worked, which was removing the element and setting it again with new values, like this (using the same use case above):

  doUpdate(key: any) {
    this.db.object(`items/${ key }`).remove();
    setTimeout(() => {
      this.db.object(`items/${ key }`).set('another value');
    }, 0);
  }

I've also tried multi path updates, which would be better (but still poor), like this:

  doUpdate(key: any) {
    const updates = {};
    updates[`items/${ key }`] = null;
    updates[`items/${ key }`] = 'another value';
    this.db.object('/').update(updates);
  }

But it didn't work (same symptom, updates the data, but don't refresh the view).

It only worked after using setTimeout when setting the new values. Of course that this is not a good approach, cause you always have to set the entire entity, but it's the only way I got what I wanted.

Well, I'm waiting for @adriancarriger to know whether this is really a bug, or I'm missing something.

peter-o commented 7 years ago

I had the same problem. I needed a quick fix so I've added a small function which adds and then removes a dummy object from the list. I call it after each update:

updateFix(path) {
    var fixObj = { isUpdateFix: true };
    var key = this.db.list(path).push(fixObj).key;
    this.db.list(path + '/' + key).remove();
}

Then in the view I use the search pipe to not display this object.

Pl4yeR commented 7 years ago

I'm facing this too.

More info: Problem only occurs when working offline. If I'm connected to the net everything is working properly in my case.

belavenuto commented 7 years ago

For me, it occurs even when I'm online.