I'd like to use NGXS to open modal which will set column visibility for datatable.
Here is my code:
state.ts file:
@Action(OpenColumnModal)
openColumnModal(ctx: StateContext<FeedStateModel>) {
const state = ctx.getState();
const allCols = state.allColumns;
return this.modalService.openColumnVisibilityModal(allCols).pipe(tap((result) => {
ctx.setState({
...state,
allColumns: result,
userColumns: result.filter(col => col.visible)
});
})
}
modal.service.ts:
openColumnVisibilityModal(columns): Observable<any> {
const dialogRef = this.dialog.open(ColumnVisibilityModal, {
data: columns,
autoFocus: false,
hasBackdrop: true,
disableClose: true
});
return dialogRef.afterClosed();
}
When I'm using modal opened by NGXS, after closing the state event isn't emitted. After that, I need to click somewhere to call the callback function inside openColumnModal function.
I'm using Angular Material dialog.
Does anyone know how to call callback function automatically after closing modal?
Thanks in advance:)
Try to use subscribe instead of pipe:
To add to Armen's anser: Pipe is used to chain different functions and returns an
Observable
. Tap is used within pipe to run a side effect (like logging values in between pipes to debug, etc).Check out this RxJS docs page and you can read:
In other words: if you don't subscribe to the Observable returned by your pipe, the pipe won't run at all. Your fix:
P.S. - other answers that advise to subscribe inside the action handler are not correct, as NGXS doesn't work like that!
Your current approach is correct, the problem is that action handlers are run outside Angular's zone. Just inject the
NgZone
class into your state and execute the code within Angular's zone:When you dispatch any action - NGXS invokes the appropriate handlers for this action within the parent zone using
runOutsideAngular
, this is by design.You can also look at the executionStrategy option that allows to provide own class or use existing
NoopNgxsExecutionStrategy
, that doesn't useNgZone
class at all.