Angularfire: forEach works with snapshotChanges(), but not .map, even though the documentation says it should.

Created on 5 Oct 2017  路  18Comments  路  Source: angular/angularfire

Version info

Angular:
4.2.4

Firebase:
"firebase": "^4.5.0"

AngularFire:
"angularfire2": "^5.0.0-rc.1"

Other (e.g. Ionic/Cordova, Node, browser, operating system):
AngularCLI Project, Windows 7

How to reproduce these conditions

allUsers: AngularFirestoreCollection<any>;
users: Observable<any[]>;

//then in constructor:
this.allUsers = db.collection("users");
this.users = this.allUsers.snapshotChanges();

// This works:
this.users.forEach( user => {
  user.forEach( userData =>{
    let data = userData.payload.doc.data();
    let id = userData.payload.doc.id;
    console.log( "ID: ", id, " Data: " , data );
    });
});
// This doesn't work, when it should:
this.users.map(actions => {
  return actions.map(a => {
    const data = a.payload.doc.data();
    const id = a.payload.doc.id;
    console.log( "ID: ", id, " Data: " , data );
    return { id, data };
    });
});

Debug output

* Errors in the JavaScript console *
None.

Expected behavior

.map() should work.

Actual behavior

.map() doesn't work.

Most helpful comment

After upgrading to ^5.0.0-rc.9 it finally works like this:

this.tasksCollection.snapshotChanges().pipe(
        map(
            changes => { return changes.map(a => {
            const data = a.payload.doc.data() as Task;
            data.id = a.payload.doc.id;
            return data;
          });
          }
        )).subscribe();

All 18 comments

.subscribe() also works as it should, and .map() works if inside a .subscribe(), like so:

  this.users.subscribe( data =>{
    if (data) {
        console.log("Subscribe: ", data);
        data.map( test =>{
            console.log("Map: ", test.payload.doc.data());
        });         
    }
  })

valueChanges returns an Observable, therefore you can do anything on it that you could on any other Observable.
Therefore map works as expected as you can see here: https://stackblitz.com/edit/angular-template-firebase-uxldsj?file=app/app.module.ts

@Toxicable I tried that code now, both with valueChangesand with snapshotChanges, and .map() still doesn't work for me.

Also, I didn't put<Type> in this.allUsers = db.collection("users"); before, but now that I did like this this.allUsers = db.collection<any>("users"); it still doesn't work.

But since it works in the link you provided, I guess it's a problem on my end, maybe I missed something.

@Metsuryu What error do you get ?

@Toxicable No errors, the console.log just doesn't print anything. I'm trying a few more things and I'll update this post later with what I find.

I don't know if firebase.database().enableLogging would show something, since I can't enable it, firebase.database().enableLogging(true); shows me an error saying enableLogging doesn't exist when I try it.

@Metsuryu are you subscribing the second one anywhere?

@sionfletcher No, should I?
In the documentation there is no mention of having to subscribe it before using .map().

Edit: It does work if I subscribe right after I call .map(), thank you @sionfletcher I had no idea I had to do that.

@Metsuryu I don't think the observable will emit any values until it's subscribed to, or you use users | async in your template.

@sionfletcher hey man, i need ur help with something similar to this post, i am trying to return the id from the payload of the doc in a method but struggling to do so, let me know if u can help - sabeeh.[email protected]

@sabeehshah show us the code.

After upgrading to ^5.0.0-rc.9 it finally works like this:

this.tasksCollection.snapshotChanges().pipe(
        map(
            changes => { return changes.map(a => {
            const data = a.payload.doc.data() as Task;
            data.id = a.payload.doc.id;
            return data;
          });
          }
        )).subscribe();

@fobando93 the map still not working inside .pipe( map ), what i have to do?

is working for me with the map inside the pipe()
thanks
i am in the last version of rxjs and firebase ( 11/06/2018)

import {
AngularFirestore,
AngularFirestoreCollection,
AngularFirestoreDocument
} from 'angularfire2/firestore';

import { Observable } from 'rxjs/Observable';
import { map } from 'rxjs/operators';

this.tasks = this.tasksCollection.snapshotChanges().pipe(
map(changes => {
return changes.map(a => {
const data = a.payload.doc.data() as Task;
data.id = a.payload.doc.id;
console.log("hola");
return data;
});
}));

i do that in my code

After upgrading to ^5.0.0-rc.9 it finally works like this:

this.tasksCollection.snapshotChanges().pipe(
        map(
            changes => { return changes.map(a => {
            const data = a.payload.doc.data() as Task;
            data.id = a.payload.doc.id;
            return data;
          });
          }
        )).subscribe();

THANKS ITS WORK FOR ME , TE AMO :$

After upgrading to ^5.0.0-rc.9 it finally works like this:

this.tasksCollection.snapshotChanges().pipe(
        map(
            changes => { return changes.map(a => {
            const data = a.payload.doc.data() as Task;
            data.id = a.payload.doc.id;
            return data;
          });
          }
        )).subscribe();

It took a while to find but this works

@gifthlong I'm trying with latest version and it doesn't

its not working even for me

Was this page helpful?
0 / 5 - 0 ratings