Inside my NGXS store I have the following async selector
@Selector()
static async mainState(store: IMyStore): Promise<IMyState> {
return this.getActiveState(store);
}
If I now subscribe to this selector
@Select(MyStore.mainState) state$: Observable<IMyState>;
If I subscribe to this stream I receive promises not IMyState objects. So I have to do:
this.state$.subscribe(p => {
p.then(state => { ... });
});
I can cast the promise into a rxjs stream but then I receive streams
this.state$.subscribe(s => {
s.subscribe(state => { ... });
});
So my question is, is there a way to support async selectors in ngxs?
The @Selector is used to "slice a specific portion of the state from the global state container" (not to call async function within it as I know).
You can achieve what you're trying to do, like the following:
@Action to handle the async process.mainState value.async function, update the mainState with the proper value.@Selector function to return the mainState.action within your component.@Select property within your component to get the mainState from your state.Your code could look like the following:
mystore.state.ts
@Selector()
static mainState(state: IMyStore): IMyState {
return state.mainState;
}
@Action(LoadMainState)
async loadMainState(ctx: StateContext<IMyStore>) {
const _activeState = await this.getActiveState(store);
ctx.patchState({ mainState: _activeState });
}
example.component.ts
@Select(MyStore.mainState) state$: Observable<IMyState>;
ngOnInit(): void {
this.store.dispatch(new LoadMainState());
}
Or if you still don't want to create an awkward piece of store you can flatten with switchAll(). Doing so you avoid ugly subscribe inside subscribe.
@Select(MyStore.mainState) stateHigherOrder$: Observable<Observable<IMyState>>;
state$!:Observable<IMyState>;
ngOnInit(): void {
this.state$ = this.stateHigherOrder$.pipe(switchAll());
}
And now this.state$ is what you wanted