31

I have below code in an Angular application which is using AngularFire2.

TypeScript:

constructor(db: AngularFirestore) {
    this.booksCollectionRef = db.collection<Book>('books');

    this.books = this.booksCollectionRef.snapshotChanges().map(actions => {
        return actions.map(action => {
            const data = action.payload.doc.data() as Book;
            const id = action.payload.doc.id;
            return { id, ...data };
        });
    });
}

HTML:

<md-list>
    <md-list-item *ngFor="let book of books | async">
        <h4 md-line>{{book.name}}</h4>
    </md-list-item>
</md-list>

This code retrieves and binds data as expected (removes items when collection updated), now I want to sort the collection by a given column. I tried to use firebase orderBy clause, but I can not figure out how to use it with snapShotChanges() method.

alex kucksdorf
  • 2,573
  • 1
  • 15
  • 26
Nalaka526
  • 11,278
  • 21
  • 82
  • 116
  • 2
    Have you tried: `this.books = this.booksCollectionRef.orderBy('name','desc').snapshotChanges().map(actions =>` – Gal Bracha Oct 08 '17 at 12:38
  • 2
    @GalBracha that also does not work. `Property 'orderBy' does not exist on type 'AngularFirestoreCollection'` – Nalaka526 Oct 08 '17 at 15:37
  • Have you tried the default `sort()` function of TypeScript ? If not then please provide us with the structure of your `this.books`. – M0nst3R Oct 10 '17 at 16:52
  • @GhassenLouhaichi, Not yet. That would be my last option.But I'm trying to get this done within 'snapshotChanges()' because I may need to use some other functions in firestore collection, similarly. – Nalaka526 Oct 10 '17 at 16:59
  • I am not following, if you are using `.map` after your `snapshotChanges()` call, can't you simply follow that by a `.sort` call to sort your results ? – M0nst3R Oct 10 '17 at 17:01
  • @GhassenLouhaichi Yes I can, But say I want to use `where` clause instead of `orderBy`, then if I select all the records from firestore and filtering it using TypeScript methods would be inappropriate, I guess. – Nalaka526 Oct 10 '17 at 17:06

3 Answers3

64

The following should work for your use case:

this.booksCollectionRef = db.collection<Book>('books', ref => ref.orderBy('order field'));

Take a look at the documentation of AngularFirestore for further information on this topic.

alex kucksdorf
  • 2,573
  • 1
  • 15
  • 26
11
this.announcementCollectionRef = afs.collection<Announcement>('announcements', ref => ref.orderBy('createdAt', 'desc'));
this.announcements = this.announcementCollectionRef.snapshotChanges().map(actions => {
    return actions.map(a => {
        const data = a.payload.doc.data() as AnnouncementId;
        const id = a.payload.doc.id;
        return { id, ...data };
    });
});
OroshiX
  • 712
  • 1
  • 8
  • 28
Clayton Allen
  • 239
  • 3
  • 15
0

Not sure about Angular Fire, but you can try using the Firebase Firestore libraries directly.

The following code works for me:

someCollectionRef
.orderBy('columnName')
.onSnapshot((snapshot) => {
snapshot.docChanges.forEach(function (change) {
...doStuff
sgt_lagrange
  • 452
  • 5
  • 6
  • 1
    Do you know why it says to me "Property 'forEach' does not exist on type '(options?: SnapshotListenOptions) => DocumentChange[]'." please? – Laker May 09 '18 at 22:10