如何在ngrx / effects中使用promise

时间:2017-11-17 21:31:22

标签: angular firebase ngrx ngrx-store ngrx-effects

我在Angular中使用@ ngrx / store和@ngrx / effects与Firebase身份验证。

这是构造函数:

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

这是效果:

@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()));

此代码按预期工作,但我需要存储在Firestore文档中的其他值,我可以通过这种方式检索它们:

[...]
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
                };
            });
[...]

但由于这是一个承诺,我无法使用userRef我正在使用user。 这个问题有解决方案吗?

1 个答案:

答案 0 :(得分:1)

只需要在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()));