Closed hfabisiak closed 4 years ago
Originally, I was planning to add functionality similar to redux thunks as a native API, which could provide this kind of feature. It ended up causing a lot of complexity, and opened the door for abuse of the unidirectional data-flow.
The way I view it is that an action is simply a dispatched event. The dispatcher shouldn't care what happens to the acton or if it ever modifies the state. Observers of the state should be used instead to trigger any new action that might be needed.
For the example you provided, I might handle fetchTodos()
in the following ways:
An optional closure could be passed to fetchTodos()
that provides a derived publisher from the service call. It could be used to further perform any extra operations on the todos before they're added to the state:
let action = fetchTodos { (todos: AnyPublisher<[Todo], Error>) in
todos.filter { ... }.map { ... } // The returning publisher is then mapped to a `setTodos` action.
}
dispatch(action)
It might be possible to pull this off inside a containing publishable action plan. It's kind of a hack, but you could observe off of the store.didChange
property using something like firstWhere(_:)
to wait for the fetchTodos()
to update the state. The store.state
property inside an action plan always provides the latest snapshot of the state similar to getState()
in redux thunk.
I'm working on a solution using a new API on the ActionPlan itself:
let chainedActions = firstActionPlan.then(secondActionPlan).then(thirdActionPlan)
// Or
let chainedActions = firstActionPlan.next(secondActionPlan, thirdActionPlan)
Each plan would wait for the previous one to fully complete or be cancelled before running (Useful for plans that return a publisher). The method would return a new version of the first action plan that internally keeps a copy of the next ones to run after it finishes.
There's no data passing between the action plans. Instead, the store's state can be accessed to retrieve anything necessary.
Added the feature in v0.12.0
Hi! Is there a way that I can chain ActionPlan requests? Next action plan gets executed when all actions from the previous one get executed. For example:
TodoAction.fetchTodos()
.then(TodoAction.filterTodos())
.then(TodoAction.mapTodos())