Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 7 used NGRX and save token in localStorage

In my Angular application i used NGRX store and i have some problem with saved user token. Sometimes i reload my page and lost everything.

In app.component.ts implement OnInit and add there:

this.store.select('auth').subscribe(event => {
  if (event.token) {
    window.localStorage.setItem('token', JSON.stringify(event.token));
  }
});

if (window.localStorage.getItem('token')) {
  const token = JSON.parse(window.localStorage.getItem('token'));
  this.store.dispatch(new AuthActions.SetToken(token));
}

And created Effect:

@Effect()
this.actions$.pipe(
    ofType<AuthActions.TrySignin> (
        AuthActions.AuthActionTypes.TRY_SIGNIN
    ),
        switchMap(action => {
            return this.httpClient.put('http://localhost:8080/api/signin', {
                username: action.payload.username,
                password: action.payload.password
            }, {
                    observe: 'body',
                    responseType: 'text'
                }).pipe(
                    map(
                        token => {
                            this.router.navigate(['/']);
                            return new AuthActions.SetToken(token);
                        }
                    ),
                    catchError(error => {
                        return of(new AuthActions.AuthFailed(error));
                    }
                    )
                );

        }
        )
);

It is correct?

like image 993
Pionas Avatar asked Jan 28 '23 02:01

Pionas


1 Answers

I would suggest you to not do this inside your components. They will become harder to test, plus you could end up with the same code in different components.

Instead use you can do this inside effects as Maciej suggested, for another example see https://github.com/tomastrajan/angular-ngrx-material-starter/blob/master/src/app/examples/form/form.effects.ts#L20

But personally, I like to use a meta-reducer for this - see https://github.com/timdeschryver/ngrx-family-grocery-list/blob/master/src/app/groceries/reducers/groceries.reducer.ts#L165

For example:

export function persistStateReducer(_reducer: ActionReducer<State>) {
  const localStorageKey = '__auth';
  return (state: State | undefined, action: Action) => {
    if (state === undefined) {
      const persisted = localStorage.getItem(localStorageKey);
      return persisted ? JSON.parse(persisted) : _reducer(state, action);
    }

    const nextState = _reducer(state, action);
    localStorage.setItem(localStorageKey, JSON.stringify(nextState));
    return nextState;
  };
}
like image 115
timdeschryver Avatar answered Jan 31 '23 23:01

timdeschryver