Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular FIrebase 5 objects keys not being displayed. So can't delete

The question has been answered but I'm looking for a, um, more straightforward one if available. It seems strange that we'd have to implement not one but two mappings just to have access to the object keys.

basic firebase db: enter image description here As can be seen, the course objects clearly have keys. Mark-up:

<ul>
  <li *ngFor="let course of courses$ | async">
    <b>Key:</b> {{course.$key}} <!-- doesn't show --!>
    <b>Title:</b> {{course.Title}}
    <b>Duration:</b> {{course.Duration}}
    <b>Author:</b> {{course.Author}}
    <p><button (click)="deleteCourse(course)">Remove</button></p>

    <hr> 
  </li>
</ul>

Now, the courses display just fine, but I don't know how to get a reference to the key in order to delete it. (Or perhaps I'm not using the right method on my firebaseDatabase Object). Either way, when I log the key in the console, it shows as undefined.

export class AppComponent {
  courses;
  courses$: AngularFireList<any>;

  constructor(private db: AngularFireDatabase) {
    this.courses = db.list('/courses');
    this.courses$ = this.courses.valueChanges();
  }
  ...
  deleteCourse(course) {
    console.log(course.$key); // -> undefined
    this.db.object('/courses/' + course.$key).remove();
  }
}
like image 351
PakiPat Avatar asked Nov 14 '17 17:11

PakiPat


2 Answers

Updated Answer

Rxjs have changed how it pipes data. now you have to use .pipe().

this.courses$ = this.courses.snapshotChanges().pipe(
  map(changes => 
    changes.map(c => ({ key: c.payload.key, ...c.payload.val() }))
  )
);

Original Answer

.valueChanges() contain simply data, no key with it. you need to use .snapshotChanges()

this.courses$ = this.courses.snapshotChanges().map(changes => {
  return changes.map(c => ({ key: c.payload.key, ...c.payload.val() }));
});

now just use {{course.key}}

here is your corrected code

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';

export class AppComponent {
  courseRef: AngularFireList<any>;
  courses$: Observable<any[]>;

  constructor(private db: AngularFireDatabase) {
    this.courseRef = db.list('/courses');
    this.courses$ = this.courseRef.snapshotChanges().map(changes => {
        return changes.map(c => ({ key: c.payload.key, ...c.payload.val() 
    }));
   });
  }
  ...
  deleteCourse(course) {
    console.log(course.key);
    this.db.object('/courses/' + course.key).remove();
  }
}
like image 171
Hareesh Avatar answered Nov 01 '22 19:11

Hareesh


to create an interface:

export interface Client{
    key?: string;
    firstName?: string;
    lastName?: string;
    email?: string;
    phone?: string;
    balance?:number;

}

import { Injectable } from '@angular/core';
import { AngularFireDatabase, AngularFireList, AngularFireObject} from '@angular/fire/database';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';



@Injectable()
export class ClientService {
  client: AngularFireList<any>;
  clients: Observable<any[]>;

  constructor(public db: AngularFireDatabase) {
    this.client = db.list('/clients');
    this.clients = this.client.snapshotChanges().pipe(
      map(res => res.map(c => ({ key: c.payload.key, ...c.payload.val() 
    }))

   ));

  }

  getClients(){
    return this.clients;
  }


}

import { Component, OnInit } from '@angular/core';
import { ClientService } from '../../services/client.service';
import { Client} from '../../models/client'



@Component({
  selector: 'app-clients',
  templateUrl: './clients.component.html',
  styleUrls: ['./clients.component.css']
})
export class ClientsComponent implements OnInit {
  clients:Client[];

  constructor(
    public clientService:ClientService
  ) { }

  ngOnInit(){
    this.clientService.getClients().subscribe(clients=>{
      this.clients = clients;
      console.log(this.clients);
    })


  }

}
like image 35
Pushpa Raj Panthi Avatar answered Nov 01 '22 20:11

Pushpa Raj Panthi