0
votes

I'm using AngularFirestore2v5/rxjs to connect a hybrid Ionicv3/Angularv4 mobile app to a firestore collection. I can bind to the UI when using AngularFirestore.valueChanges. Switching to snapshotChanges to retrieve the id is giving me problems. The examples provided in this thread (and video) use map and log to the console. To get that working I had to also call subscribe on the snapshot observable. Apparently it needs a subscriber before it will emit anything. I later found I could just use subscribe without preceding it with map. So now my code (simplified) looks like:

_col: AngularFirestoreCollection<_model>;
_snapshot: any;

constructor(private afs: AngularFirestore) {
  this._col = this.afs.collection('items'); //items being the name of the collection in firestore
  this._snapshot = this._col.snapshotChanges()
                    .subscribe(actions => {
                      return actions.map(snap => {
                        let id = snap.payload.doc.id;
                        let data = { id, ...snap.payload.doc.data() };
                        console.log(data); //{id: "Q6YZOzyFPvrfsxwT3uTS", field1: "a thing", field2: "another"}
                        return data;
                      });
                    });

The console log within subscribe prints the data from the store correctly. I have no idea how to bind that to the UI in an angular manner.

To get the valueChanges examples working you must put the async pipe in your UI. Doing so for the _snapshot returns:

Error: InvalidPipeArgument: ‘[object Object]’ for pipe ‘AsyncPipe’ Trying to just use the json pipe elicits:

ERROR TypeError: Converting circular structure to JSON which is fair enough. I know it’s not the correct way of doing it. So what is?

1
you dont need a async pipe when you subscribe. - Hareesh
That's an interesting sidenote. Thank you. - stephen

1 Answers

0
votes

Async pipe expect an observable which is not subscribed and expect to return a value. Async pipe will subscribe itself and output the value.

You can try

this._snapshot = this._col.snapshotChanges()
                .subscribe(actions => {
                  return actions.map(snap => {
                    let id = snap.payload.doc.id;
                    let data = { id, ...snap.payload.doc.data() };
                    console.log(data); //{id: "Q6YZOzyFPvrfsxwT3uTS", field1: "a thing", field2: "another"}

                    // use data in your html
                    this.data=data

                    return data;
                  });
                });

html

<div *ngFor="let item of data" ....

Edit 1

this.dataArray=this._col.snapshotChanges()
                .map(actions => {
                  return actions.map(snap => {
                    let id = snap.payload.doc.id;
                    let data = { id, ...snap.payload.doc.data() };
                    return data;
                  })
                })

html

<div *ngFor="let item of dataArray | async" ....