Reputation: 2522
In the code I have something like:
this.store.dispatch(new LoadGame(id));
this action is handled by one of the @Effect
and fires new LoadGameSuccess(game)
. Than this game is passed to reducer to update GameState
.
However how can I change the GameState
to reflect that game is currently being loaded? Making one more action and handle it in the reducer looks not very good. The application becomes 'actions-hell'...
Should I do this in the @Effect
?
Upvotes: 0
Views: 136
Reputation: 4422
Don't try to go against the design pattern. It's designed that way for a reason.
If you have an action that may or may not impact the state of the store based on some other logic, the right way to do it is have an effect that listens for the action, performs the logic, and then dispatches a new action.
That being said - there's no reason you can't handle the LoadGame
action in both the store and the effect. Something like this:
Your effect
@Effect()
loadGame$ = this.actions$.pipe(
ofType<LoadGame>(GameActions.LoadGame),
mergeMap(url => this.http.get<Game>("http://wherever.you.get.your.game.data.from")
.pipe(
game => [new LoadGameSuccess(game), new AnyOtherActionsHere()]
)
)
);
Your Reducer
export function reducer(state = initialState, action: GameActions): State {
switch (action.type) {
case GameActions.LoadGame:
return {
...state,
isGameLoading: true,
};
case GameActions.LoadGameSuccess:
const { game } = action.payload
return {
...state,
game
isGameLoading: false,
};
}
}
Note that there is no concern for a race condition in doing this.
Upvotes: 1