Access element of my states in my effects

51 Views Asked by At

I'm new to the ngrx world.

I'm trying to get data of my state directly in my effects.

The idea is get a type of account (publisher or advertiser) and send this information to a "success" action.

this is my effects:

import { Injectable } from "@angular/core";
import { map, exhaustMap, withLatestFrom } from 'rxjs/operators';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { AuthService } from './auth.service';
import * as fromRoot from '@app/store';
import * as fromActions from './auth.actions';
import * as fromRouter from '@app/store/router';
import { Store } from "@ngrx/store";

@Injectable()
export class AuthEffects {
    constructor(
        private authService: AuthService,
        private actions$: Actions,
        private store: Store<fromRoot.State>,
    ){}


    signIn$ = createEffect(() => 
        this.actions$.pipe(
            ofType(fromActions.Types.LOG_IN),
            map((action: fromActions.LogIn) => action.payload),
            withLatestFrom(this.store.select(fromRouter.getAccountRole)),
            exhaustMap(([payload]) => {
                return this.authService.logIn(payload.email, payload.password).pipe(
                    map((user) => {
                        return new fromActions.LogInSuccess({token: user.token, type:'advertiser'})
                    })
                )
            })
        )

    )
}

And this is my selector

import { createFeatureSelector, createSelector } from "@ngrx/store";
import { RouterReducerState } from '@ngrx/router-store';
import { RouterStateUrl } from "./router.serializer";

export const getRouterState = createFeatureSelector<RouterReducerState<RouterStateUrl>>('router');

export const getCurrentRoute = createSelector(
    getRouterState,
    (router) => router.state
)

export const getAccountRole = createSelector (
    getCurrentRoute,
    (route: RouterStateUrl) => {
        if(route.params['role']) {
            return route.params['role'];
        }
    }
)

I think I need to use withLatestFrom before exhaustMap but couldn't use it.

Thanks for your help

1

There are 1 best solutions below

4
Amer On

You're on the right track, you need to use the withLatestFrom operator to before exhaustMap, however, I think you missed passing the selector to the store.select() method.

Try something like the following:

signIn$ = createEffect(() =>
    this.actions$.pipe(
        ofType(fromActions.Types.LOG_IN),
        map((action: fromActions.LogIn) => action.payload),
        withLatestFrom(this.store.select(getAccountRole)),
        exhaustMap(([payload, accountRole]) => {
            return this.authService.logIn(payload.email, payload.password).pipe(
                map((user) => {
                    return new fromActions.LogInSuccess({ token: user.token, type: 'advertiser' });
                })
            );
        })
    )
);