Is it possible to user route resolvers with the NGXS store?
I have a test made like this, but I don't know if it is the correct way to go:
import {ActivatedRouteSnapshot, Resolve} from "@angular/router";
import {Todo} from "./todos.models";
import {Observable} from "rxjs/Observable";
import {Select, Store} from "@ngxs/store";
import {GetTodo, TodosState} from "./todos.state";
import {Injectable} from "@angular/core";
@Injectable()
export class TodoResolver implements Resolve<Todo> {
constructor(
private store:Store
) {}
@Select(TodosState.getTodo)
private todo$:Observable<Todo>;
resolve(route:ActivatedRouteSnapshot): Observable<Todo>
{
const id = <number><any> route.paramMap.get('id');
this.store.dispatch(new GetTodo(id));
return this.todo$;
}
}
When I try this, the application just hangs. No errors shown.
All help welcome. Thanks
Ignore please, I found the solution myself...
Changed code to:
@Injectable()
export class TodoResolver implements Resolve<Todo> {
constructor(
private store:Store
) {}
resolve(route:ActivatedRouteSnapshot): Observable<Todo>
{
const id = <number><any> route.paramMap.get('id');
this.store.dispatch(new GetTodo(id));
return this.store.selectOnce(TodosState.getTodo);
}
}
I think rauwebieten's solution only works for sync action. Async action will modify the store after selectOnce's execution.
I have to set up two states to deal with async actions. One is Todos State and another is RequestingTodo State.
The code looks like:
@Injectable()
export class AsyncTodoResolver implements Resolve<Todo> {
@Select(RequestingTodoState)
private todo$:Observable<Todo>;
constructor(
private store:Store
) {}
resolve(route:ActivatedRouteSnapshot): Observable<Todo> {
const id = <number><any> route.paramMap.get('id');
return this.store.dispatch(new GiveOrFetchTodo(id))
.pipe(
withLatestFrom(todo$),
map([any, todo]) => {return todo;}
);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With