Search code examples
angularfirebaseionic3angularfire5

Ionic3, AngularFire - Property 'remove' does not exist on type 'Observable<any[]>'


I have been following an outdated tutorial (this playlist in particular) and I got lost switching between AngularFire 4.0 and AngularFire 5.0. It's a simple CRUD application which implements Firebase. The code is uncouth, but I am able to view and post to the database.

I'm trying to delete an item from a node using the key in firebase, but I'm getting the error

Property 'remove' does not exist on type 'Observable<any[]>'.

Here is my .ts file:

import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams, ActionSheetController } from 'ionic-angular';
import { AngularFireList, AngularFireDatabase } from 'angularfire2/database';
import { Matatu } from '../../models/matatu/matatu.interface';
import { Observable } from 'rxjs/Observable';

@IonicPage()
@Component({
  selector: 'page-owner-dash',
  templateUrl: 'owner-dash.html',
})

export class OwnerDashPage {

  matatuListRef$: Observable<any[]>;

  constructor(public navCtrl: NavController, public navParams: NavParams, private database: AngularFireDatabase, public actionShtCrtl: ActionSheetController) {
    this.matatuListRef$ = this.database.list('matatu-list').valueChanges();

  }

  ionViewDidLoad() {
    //
  }

  selectMatatu(matatu: Matatu){
    this.actionShtCrtl.create({
      title: `${matatu.matNumberPlate}`,
      buttons: [
        {
          text: 'Edit',
          handler: () => {
            //
          }          
        },
        {
          text: 'Delete',
          role: 'destructive',
          handler: () => {
            this.matatuListRef$.remove(matatu.$key);
          }
        },
        {
          text: 'Cancel',
          role: 'cancel',
          handler: () => {
            //
          }
        }
      ]
    }).present();
  }


}

And here the .html code that displays the records.

...
<ion-list>
    <button ion-item *ngFor="let ma3 of matatuListRef$ | async" (click)="selectMatatu(ma3)">
      <h2 style="font-weight: bold;">{{ma3.matNumberPlate}}</h2>
      <h3>Driver: {{ma3.matDriver}}</h3>
      <h3>Status: {{ma3.matStatus}}</h3>
    </button>
  </ion-list>
...

I know FirebaseListObservable was refactored to AngularFireList, but I assigned my variable to the type Observable instead.

matatuListRef$: Observable<any[]>;

Bottom line, I get the error TypeError: _this.matatuListRef$.remove is not a function on the browser's console when I try to delete the record.

How can I resolve this? All suggestions and approaches are highly welcomed,but I would really appreciate it if the solutions focused on using AngularFireList.


Solution

  • remove() function is present on the list reference retrieved from Firebase and not the Observable from valueChanges().

    You need to set

    this.matatuListRef$ = this.database.list('matatu-list');
    

    Secondly, you will not get $key from valueChanges() either. You need to use snapshotChanges() in order to retrieve keys and values.

    this.matatuListAsync = this.matatuListRef$.snapshotChanges();
    

    instead of

    this.matatuListRef$ = this.database.list('matatu-list').valueChanges();
    

    You can use this.matatuListAsync in the *ngFor in the HTML

    <ion-list>
        <button ion-item *ngFor="let ma3 of matatuListAsync$ | async" (click)="selectMatatu(ma3)">
          <h2 style="font-weight: bold;">{{ma3.payload.val().matNumberPlate}}</h2>
          <h3>Driver: {{ma3.payload.val().matDriver}}</h3>
          <h3>Status: {{ma3.payload.val().matStatus}}</h3>
        </button>
      </ion-list>
    

    and finally in your remove() call,

            this.matatuListRef$.remove(matatu.payload.$key);