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?
By default, your application state gets reset when you refresh the page.
What you need to do is, save your 'auth' state to a persistant storage, like localstorage/sessionstorage.
And restore the state from localstorage/sessionstorage on startup.
I've created a library to handle this for you easily: https://github.com/larscom/ngrx-store-storagesync
npm install --save @larscom/ngrx-store-storagesync
The configuration would be something like the following for your setup
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { StoreModule, ActionReducerMap, ActionReducer, MetaReducer } from '@ngrx/store';
import { storageSync } from '@larscom/ngrx-store-storagesync';
import * as fromAuth from './auth/reducer';
export const reducers: ActionReducerMap<ISomeState> = {
auth: fromAuth.reducer
};
export function storageSyncReducer(reducer: ActionReducer<any>): ActionReducer<any> {
return storageSync<ISomeState>({
features: [
// saves the auth state to sessionStorage
{ stateKey: 'auth' }
],
storage: window.sessionStorage
})(reducer);
}
const metaReducers: Array<MetaReducer<any, any>> = [storageSyncReducer];
@NgModule({
imports: [BrowserModule, StoreModule.forRoot(reducers, { metaReducers })]
})
export class AppModule {}
That's it, if you reload the page, the state will restore from the sessionStorage (in this case)