Updating an item in a FirebaseListObservable using AngularFire 2

jloosli picture jloosli · Jun 18, 2016 · Viewed 8.6k times · Source

I'm trying to update an item in a FirebaseListObservable object in an Angular2 project using Angularfire2. The definition for the FirebaseListObservable is as follows:

export declare type FirebaseOperation = string | firebase.database.Reference | firebase.database.DataSnapshot | AFUnwrappedDataSnapshot;
export declare class FirebaseListObservable<T> extends Observable<T> {
  _ref: firebase.database.Reference | firebase.database.Query;
  constructor(_ref: firebase.database.Reference | firebase.database.Query, subscribe?: <R>(subscriber: Subscriber<R>) => Subscription | Function | void);
  lift<T, R>(operator: Operator<T, R>): Observable<R>;
  push(val: any): firebase.database.ThenableReference;
  update(item: FirebaseOperation, value: Object): firebase.Promise<void>;
  remove(item?: FirebaseOperation): firebase.Promise<void>;
  _checkOperationCases(item: FirebaseOperation, cases: FirebaseOperationCases): firebase.Promise<void>;
}

I have a service to show, save, delete, and update the houses that looks like the following:

@Injectable()
export class HousesService {
  private _houses$:FirebaseListObservable<IHouse[]>;
  constructor(private af:AngularFire) {
    this._houses$ = this.af.database.list('/houses');
  }
  save(house:IHouse) {
    if (house.hasOwnProperty('$key')) {
      this._houses.update('/houses/'+house.$key).set(house);
    } else {
      this._houses$.push(house);
    }
  }
  remove(id:any) {
    this._houses$.remove(id);
  }
}

where houses$ is the FirebaseListObservable and house is an item from the list. House is an object that looks like the following:

{
  name: "Mrs. Friendly", 
  notes: "Watch out for fence!", 
  street: "2530 Adams Ave.", 
  $key: "-KKQWsf26apDiXZNExZd"
 }

When I try to save/update an existing item, I get the following error:

Uncaught Error: Firebase.update failed: First argument contains an invalid key ($key) in path /$key. Keys must be non-empty strings and can't contain ".", "#", "$", "/", "[", or "]"

I've tried putting the original object in the first parameter, putting the full URL there, and almost every combination you can think of. According to the definition for the Observable, the _ref should work there as well. I've also tried pulling the key out of the data to be stored and nothing seems to work. The only thing that seems to work is to remove the update line completely and use the following:

this.af.database.object('/houses/'+house.$key).set(house);

I'm curious what I should have put in the first parameter so the update method would work.

I'm using Angular 2 rc-1, firebase 3.0.5, and angularfire 2.0.0-beta.1

Answer

ialexander picture ialexander · Jun 21, 2016

Your version of Angularfire is slightly older than mine but for your save method, I think you can just pass the key of the house to save (house.$key) along with an object containing the updated data.

this._houses.update(house.$key, house);

I think by passing the '/houses/' part, the error is being thrown because the $key can't start with '/'.