Reputation: 564
When the application is initialize, I want to load user already (assuming there's a token in localStorage). I followed this guide, https://www.intertech.com/Blog/angular-4-tutorial-run-code-during-app-initialization/ but I'm lost right now in how would I incorporate it with ngxs, especially with my setup.
This function is called when the app is initialized:
initializeApp() {
const token = localStorage.getItem('token');
if (token) {
this.store.dispatch(new CheckSession(token));
//hold the user
}
}
Action
@Action(CheckSession)
checkSession(sc: StateContext<SessionStateModel>, { payload }: CheckSession) {
sc.patchState({
isLoading: true,
token: payload
});
this.sessionService.checkSession()
.subscribe(response => {
sc.dispatch(new CheckSessionSuccess(response));
}, error => {
sc.dispatch(new CheckSessionFailed(error));
});
}
I'm chaining the actions in the state, and I want my app to finish the entire chain of actions first before proceeding with the app.
Is this possible or am I doing this the wrong way?
Upvotes: 0
Views: 3171
Reputation: 11202
Based on the async nature of code executions, consider this approach instead:
ofActionSuccessful()
of CheckSessionXxx
that will change route/page/component accordingly.CheckSession
. The outcome of this action will be handled by previous step.The idea is avoid "waiting for process to complete" before rendering UI. Instead, always render UI based on current state (e.g. it is loading...). As async operations cause application state to change, update UI reactively.
This is not a coding solution but suggesting a design/thinking change - otherwise you will be trying to "wait" in many scenarios (IMHO, is like fighting the 'system'). Hope this helps.
Upvotes: 2
Reputation: 222657
I think you should implement this using AuthGuard,
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private _auth: AuthService, private _store: Store) {}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
return this._isAuthenticated$.pipe(
map(a => {
if (a) {
return true;
}
this._store.dispatch(new CheckSession(state.url));
return false;
})
);
}
@Select(AuthState.isAuthenticated)
private _isAuthenticated$: Observable<boolean>;
}
and then use it before you actually call the component. You can check the following sample repository
.
Upvotes: 0