Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular2 @ngrx/store / effects - where to call service functions

I'm making an Angular 2 app with @ngrx/store and @ngrx/effects.

I'm struggling with understanding where to put logic outside of actions/effects etc and where to call service functions.

For example, with authentication...

  1. When a user clicks login this dispatches an AUTH_REQUEST action with the login credentials as the payload.
  2. An effect looks for this action an calls the API.
  3. A successful result calls the AUTH_SUCCESS action with the token, username etc in the response object as a payload which goes to the reducer to update the AuthState.

eg: In AuthEffects

@Effect() authenticate$ = this.updates$
.whenAction(AuthActions.AUTHENTICATE_REQUEST)
.switchMap(update => this.api.post('/authenticate', update.action.payload)
  .map((res:any) => ({type: AuthActions.AUTHENTICATE_SUCCESS, payload: res.json()}))
  .catch((err:any) => Observable.of({ type: AuthActions.AUTHENTICATE_ERROR, payload: err }))
);

In AuthReducer

 case AuthActions.AUTHENTICATE_SUCCESS:
  return Object.assign({}, state, <AuthState>{
    processing: false,
    failed: false,
    isLoggedIn: true,
    token: action.payload.token,
    username: action.payload.username,
    accountId: action.payload.accountId,
  });

What I want to know is:

  1. Where to call the router to change pages after an AUTH_SUCCESS action is processed. Do I do this from within the effects Reactive chain or....??
  2. I have a AuthService that needs to store the credentials (token etc) in LocalStorage. Where should I call this to "store the token" ie authService.store(userCredentials).

Any help appreciated.

like image 842
markstewie Avatar asked Aug 15 '16 00:08

markstewie


People also ask

How do you call an effect in NgRx?

You need to run this command npm install @ngrx/effects — save to install required dependencies. You have to define the actual services to make the API calls. Finally, you need to register all the effects with the EffectsModules and import this module into your main module or feature module.

Where does NgRx store its data?

Where Does NgRx Store Data? NgRx stores the application state in an RxJS observable inside an Angular service called Store. At the same time, this service implements the Observable interface. So, when you subscribe to the store, the service actually forwards the subscription to the underlying observable.

What is @effect in Angular?

} ​@ngrx/effects provides an Angular actions$ service (which is also an Observable ) to emit every action that has been dispatched by your application in a single stream. Its ofType() method can be used to filter the one or more actions we're interesting in before adding a side-effect.


1 Answers

Clearly, this isn't a definitive answer; it's just what I chose to do.

The CodeSequence/ngrx-‌​store-router implements actions for the v3 router. However, it doesn't implement a action creator - just the string types. I used a simple action creator so that I don't have to have to have action literals all over the place:

import * as ngrxStoreRouter from "ngrx-store-router";

@Injectable()
export class RouterActions {

    static NAVIGATE: string = ngrxStoreRouter.RouterActions.navigating;
    navigate(url: string): Action {

        return {
            payload: { url },
            type: RouterActions.NAVIGATE
        };
    }
}

And I used an effects class to dispatch the router actions:

@Injectable()
export class RouterEffects {

    ...

    @Effect()
    createUser(): Observable<Action> {

        return this.stateUpdates_
            .whenAction(AuthActions.CREATE_USER_SUCCESS)
            .map((update) => update.action.payload)
            .switchMap((payload) => {

                return Observable.of(this.routerActions_.navigate("/on-board"));
            });
    }

    ...
}

My reasoning was this doesn't involve the authentication effects knowing anything about routing, it makes it easy to write tests for router effects, and the router actions fit in nicely with the @ngrx/store-devtools.

Regarding your second question, I'd be inclined to wire it up to a ..._SUCCESS action in an effect.

I'd be interested in hearing about alternative approaches.

like image 125
cartant Avatar answered Nov 15 '22 23:11

cartant