How to use a promise in ngrx/effects

Viewed 4342

I'm using @ngrx/store and @ngrx/effects with Firebase authentication in Angular.

This is the constructor:

constructor(
        private actions: Actions,
        private afAuth: AngularFireAuth,
        private db: AngularFirestore,
        private router: Router
    ) {}

This is the effect:

@Effect()
    getUser: Observable<Action> = this.actions
        .ofType(authActions.GET_USER)
        .map((action: authActions.GetUser) => action.payload)
        .switchMap(payload => this.afAuth.authState)
        .map(authData => {
            if (authData) {
                const user = new User(
                    authData.uid,
                    authData.displayName,
                    authData.email,
                    authData.photoURL
                );

                return new authActions.Authenticated(user);
            } else {
                return new authActions.NotAuthenticated();
            }
        })
        .catch(err => Observable.of(new authActions.AuthError()));

this code works as expected, but I need other values that are stored in a Firestore document and I can retrieve them in this way:

[...]
if (authData) {
    const userRef = this.db.firestore
        .collection('users')
        .doc(authData.uid)
        .get()
        .then(doc => {
            const userData = doc.data();
                return {
                    uid: userData.uid,
                    displayName: userData.displayName,
                    email: userData.email,
                    photoURL: userData.photoURL,
                    role: userData.roles
                };
            });
[...]

But since it is a promise I can't use userRef where I'm using user. Is there a solution to this problem?

1 Answers

Only a matter to move a level up the switchMap.

@Effect()
getUser: Observable<Action> = this.actions
    .ofType(authActions.GET_USER)
    .map((action: authActions.GetUser) => action.payload)
    .switchMap(payload =>
        this.afAuth.authState.switchMap(auth => {
            if (auth) {
                return this.db.doc<User>(`users/${auth.uid}`).valueChanges();
            } else {
                return Observable.of(null);
            }
        })
    )
    .map(authData => {
        if (authData) {
            const user = new User(
                authData.uid,
                authData.displayName,
                authData.email,
                authData.photoURL,
                authData.roles
            );

            return new authActions.Authenticated(user);
        } else {
            return new authActions.NotAuthenticated();
        }
    })
    .catch(err => Observable.of(new authActions.AuthError()));
Related