From 3486ce662fab9a036c60563f2074a9ef3b424cf0 Mon Sep 17 00:00:00 2001 From: simonxabris Date: Sun, 30 Aug 2020 13:31:56 +0200 Subject: [PATCH] feat: map document ID to the provided idField in a collection group query --- docs/firestore/querying-collections.md | 2 +- .../collection-group/collection-group.spec.ts | 13 ++++++++++++ .../collection-group/collection-group.ts | 20 +++++++++++++++++-- 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/docs/firestore/querying-collections.md b/docs/firestore/querying-collections.md index a3d849374..7028bd452 100644 --- a/docs/firestore/querying-collections.md +++ b/docs/firestore/querying-collections.md @@ -193,7 +193,7 @@ ngOnInit() { ... // Get all the user's comments, no matter how deeply nested this.comments$ = afs.collectionGroup('Comments', ref => ref.where('user', '==', userId)) - .valueChanges({ idField }); + .valueChanges({ idField: 'docId' }); } ``` diff --git a/src/firestore/collection-group/collection-group.spec.ts b/src/firestore/collection-group/collection-group.spec.ts index 4c199fb17..aa4b094ce 100644 --- a/src/firestore/collection-group/collection-group.spec.ts +++ b/src/firestore/collection-group/collection-group.spec.ts @@ -134,6 +134,19 @@ describe('AngularFirestoreCollectionGroup', () => { }); }); + it('should return the document\'s id along with the data if the idField option is provided.', async () => { + const ITEMS = 4; + const DOC_ID = 'docId'; + const { stocks } = await collectionHarness(afs, ITEMS); + + const sub = stocks.valueChanges({idField: DOC_ID}).subscribe(data => { + const allDocumentsHaveId = data.every(d => d.docId !== undefined); + + expect(allDocumentsHaveId).toBe(true); + sub.unsubscribe(); + }); + }); + }); describe('snapshotChanges()', () => { diff --git a/src/firestore/collection-group/collection-group.ts b/src/firestore/collection-group/collection-group.ts index 1c3aff9fd..24b429b85 100644 --- a/src/firestore/collection-group/collection-group.ts +++ b/src/firestore/collection-group/collection-group.ts @@ -76,12 +76,28 @@ export class AngularFirestoreCollectionGroup { /** * Listen to all documents in the collection and its possible query as an Observable. + * + * If the `idField` option is provided, document IDs are included and mapped to the + * provided `idField` property name. */ - valueChanges(): Observable { + valueChanges(): Observable; + // tslint:disable-next-line:unified-signatures + valueChanges({}): Observable; + valueChanges(options: {idField: K}): Observable<(T & { [T in K]: string })[]>; + valueChanges(options: {idField?: K} = {}): Observable { const fromCollectionRefScheduled$ = fromCollectionRef(this.query, this.afs.schedulers.outsideAngular); return fromCollectionRefScheduled$ .pipe( - map(actions => actions.payload.docs.map(a => a.data())), + map(actions => actions.payload.docs.map(a => { + if (options.idField) { + return { + [options.idField]: a.id, + ...a.data() + } as T & { [T in K]: string }; + } else { + return a.data(); + } + })), this.afs.keepUnstableUntilFirst ); }