Angularfire: How to get the key of each item on a list query (collection().ValueChanges())

Created on 5 Jan 2019  路  3Comments  路  Source: angular/angularfire

Version info

Angular: 6.1.0

Firebase: 5.5.4

AngularFire: 5.1.1

How to reproduce these conditions

Steps to set up and reproduce

book: any = {};
bookList: any[] = [];

constructor (private db: AngularFirestore) {}

ngOnInit {
  this.book = this.db.doc('path/to/books/shrek').valueChanges();
  this.bookList = this.db.collection('path/to/books').valueChanges();

  // Observing Changes

  this.book.subscribe(p => console.log('Selected book', p));
  this.bookList.subscribe(p => console.log('Book list', p));
}

```HTML

{{book.title}}

{{book.story}}

ID: {{book.$key}}

```HTML
<a routerLink="/story/{{item.$key}}" *ngFor="let item of bookList | async">{{item.title}}</a>

Sample data

"books": {
  "shrek": {
    "title": "Shrek the Ogre"
  },
  "tangled": {
    "title": "The magic of Rapunzel"
  }
}

Debug output

_$key_ or _id_ is missing in query result.

Result in the JavaScript console

Expected behavior

query-result-expection

Actual behavior

query-result

Most helpful comment

This seems a little ridiculous for such a simple and absolutely essential feature or am I missing something? One would absolutely expect to have a key exposed on an object or else there's little you can do with it.

All 3 comments

Oh, I think I've gotten it.
Use _snapshotChanges()_ instead of _valueChanges()_
The map the observable to an array with the _$key_ or _id_

...

public getItemList(path: string, query?: QueryFn) { // Get list of items in a path
  return this.db.collection(path, query).snapshotChanges().pipe(map((mutation: any[]) => mutation.map(p => {
    return { ...p.payload.doc.data(), '$key': [p.payload.doc.id][0] };
    // OR
    return { ...p.payload.doc.data(), 'id': [p.payload.doc.id][0] };
  })));
}

...

Read the Documentation

This seems a little ridiculous for such a simple and absolutely essential feature or am I missing something? One would absolutely expect to have a key exposed on an object or else there's little you can do with it.

This doesn't seem to work anymore as doc is no longer available:

Property 'doc' does not exist on type 'DatabaseSnapshot'

Was this page helpful?
0 / 5 - 0 ratings