Search code examples
firebasefirebase-realtime-databaseionic3angularfire5

AngularFire5 — Reference.update failed: First argument contains a function in property


I'm trying to save changes to an existing node in my Firebase DB, but I'm getting this error here:

Reference.update failed: First argument contains a function in property 'matatu-list.-L-RMcqjnladFM5-V80b.payload.node_.children_.comparator_' with contents = function NAME_COMPARATOR(left, right) { return util_1.nameCompare(left, right); }

I want to edit an item basing on its respective key (which is passed from another page through navParams).

Here is the interface I used to structure the DB:

interface.ts

export interface Matatu {
    $key?: string;
    matNumberPlate: string;
    matSacco: string;
    matDriver: string;
    matAccessCode: string;
    matStatus: string;
    matTracker: string;
    matLocation: string;

    //Optionals
    payload?:any;
    key?:any;

}

The .ts and .html code that's meant to update the record:

.ts

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


@IonicPage()
@Component({
  selector: 'page-edit-ma3',
  templateUrl: 'edit-ma3.html',
})
export class EditMa3Page {

  matatuRef$: AngularFireObject<Matatu>;
  matatuAsync$: any;
  matatu = {} as Matatu;
  sub: Subscription;

  constructor(public navCtrl: NavController, public navParams: NavParams, private database: AngularFireDatabase) {

    const matKey = this.navParams.get('matKey');
    this.matatuRef$ = this.database.object(`matatu-list/${matKey}`);
    this.matatuAsync$ = this.matatuRef$.snapshotChanges();
    //console.log(matKey);

    this.sub = this.matatuAsync$.subscribe(
      matatu => this.matatu = matatu
    )
  }

  editMatatu(matatu : Matatu){
    this.matatuRef$.update(matatu);

    this.navCtrl.pop();
  }

  ionViewWillLeave(){
    this.sub.unsubscribe();
  }

}

.html

<ion-content>
  <ion-list>
    <ion-list-header>
      Matatu Details 
    </ion-list-header>

    <ion-item>
        <ion-label>Sacco</ion-label>
        <ion-input type="text" [(ngModel)]="matatu.matSacco"></ion-input>
    </ion-item>

    <ion-item>
        <ion-label>Driver</ion-label>
        <ion-input type="text" [(ngModel)]="matatu.matDriver"></ion-input>
    </ion-item>

    <ion-item>
          <ion-label> Access Code</ion-label>
          <ion-input type="password" [(ngModel)]="matatu.matAccessCode"></ion-input>
    </ion-item>

  </ion-list>
  <ion-list radio-group [(ngModel)]="matatu.matTracker">
    <ion-list-header>
      Preferred Tracking 
    </ion-list-header>

    <ion-item>
        <ion-label>GPS</ion-label>
        <ion-radio checked="true" value="GPS"></ion-radio>
    </ion-item>

    <ion-item>
        <ion-label>Driver's Location</ion-label>
        <ion-radio value="Driver's Location"></ion-radio>
    </ion-item>
  </ion-list>

  <div padding>
    <button ion-button block (click)="editMatatu(matatu)">Save Changes</button>
  </div>
</ion-content>

How do I go about rectifying this? I'd appreciate it if it was pointed out to me where I went wrong, and what other approaches can get this done(even the dirty ones!).


Solution

  • You can pass the key in a placeholder variable or you could just concatenate it like so:

    this.matatuRef$ = this.database.object(`matatu-list/`+ matKey);
    

    Do keep in mind this is not a good approach, but it'll do the trick.

    Firebase fires this error when you try to push data that contains a function, or a datatype instead of data values.

    Basing on your interface, and the values you are passing from you template, your
    update method should be like this:

    editMatatu(matatu : Matatu){
    
        this.matatuRef$.update({
          matDriver: this.matatu.matDriver,
          matAccessCode: this.matatu.matAccessCode,
          matSacco: this.matatu.matSacco
        });
    
    
      }