# Publisher dispatcher ## Overview The publisher dispatcher handles a common challenge in a Redux application where there is some async task and we need to track the progress of that task. We may need to know that the task is *loading*, or *completed*, or that it has *failed* or been *cancelled*. The publisher dispatcher turns this: ```swift dispatch(AppAction.documentSave.loading) document.save() .handleEvents(receiveCancel: { dispatch(AppAction.documentSave.cancelled) }) .sink( receiveCompletion: { completion in if case .failure(let error) = completion { dispatch(AppAction.documentSave.failed(error)) } }, receiveValue: { version in dispatch(AppAction.documentSave.finished(version)) } .store(in: &cancellables) ``` into this: ```swift document.save() .stateDispatcher(dispatch, statePath: \AppState.saveStatus) .sink(receiveCompletion: { _ in}, receiveValue: {_ in }) .store(in: &cancellables) ``` ## Setup Your store needs to know how to process publisher dispatcher actions. Cloe includes a reducer for this purpose. You can use `combinedReducer` to install it in your store. ```swift let store = AppStore( reducer: combinedReducer(appReducer, publisherDispatcherReducer), state: AppState(), middlewares: [createPublisherMiddleware()]) ``` Alternatively, you can add the following line to your own reducer: ```swift (action as? PublisherDispatcherAction)?.update(&state) ``` ## Usage: `PublisherStatus` Use `PublisherStatus` when you only need to track the status of the publisher, not it's output. First declare an object in your store: ```swift var saveStatus: PublisherStatus = .initial ``` Then inside of a `PublisherAction` or `RetainedPublisherAction`: ```swift publisher .statusDispatcher(dispatch, statePath: \AppState.saveStatus) ``` ## Usage: `PublisherState` Use `PublisherState` when you'd also like to track the most recent output of your Publisher. First declare an object in your store: ```swift var saveStatus: PublisherState = .initial ``` Then inside of a `PublisherAction` or `RetainedPublisherAction`: ```swift publisher .stateDispatcher(dispatch, statePath: \AppState.saveStatus) ```