1.0.0 • Published 5 years ago

redux-async-dispatcher v1.0.0

Weekly downloads
4
License
MIT
Repository
github
Last release
5 years ago

Redux-Async-Dispatcher

Redux middleware for handling asynchronous functions, complying with the Flux Standard Action.

Motivation

A common pattern when using Redux is to dispatch actions to call asynchronous APIs that will resolve in a change of the application state while keeping track of the state of the API request, which ends up adding bolierplate code in actions and reducers.

With Redux-Async-Dispatcher, use a single action type to keep track of the state of an asynchronous API call. Metadata is automatically dispatched by the middleware at request and when resolved, all in accordance with the FSA.

Installing

Using npm:

npm install redux-async-dispatcher

Using yarn:

yarn add redux-async-dispatcher

In redux store creation, use applyMiddleware():

// store.js

import { createStore, applyMiddleware } from 'redux';
import asyncMiddleware from 'redux-async-dispatcher';
import rootReducer from './reducers/index';

const store = createStore(rootReducer, applyMiddleware(asyncMiddleware));

Usage

Receives a Flux Standard Action whose payload is a promise, and will:

  • dispatch a copy of the action BEFORE resolving the promise with:
    • payload: null,
    • meta: { isLoading: true }
  • dispatch a copy of the action AFTER resolving the promise with:
    • payload: resolved value of the promise (or error object if promise is rejected),
    • meta: { isLoading: false }
    • error: true (only if error occurs)

Example

// action.js

const FETCH_TODOS = 'FETCH_TODOS';

export const fetchTodos = {
    type: FETCH_TODOS,
    payload: fetch('/api/todos').then(resp => resp.json())
};
// reducer.js

const initialState = {
    todos: [],
    isLoading: false,
    error: undefined
};

export default function reducer(state = initialState, action) {
    switch (action.type) {
        case FETCH_TODOS:
            return {
                todos: action.error ? [] : action.payload,
                isLoading: action.meta.isLoading,
                error: action.error
            };
        default:
            return state;
    }
}