redux-async

dispatch async actions in redux

Usage no npm install needed!

<script type="module">
  import reduxAsync from 'https://cdn.skypack.dev/redux-async';
</script>

README

redux-async

NPM version Build status Test coverage Downloads

RSA-compliant actions which resolve when any prop is a promise middleware for Redux.

Install

npm install --save redux-async

Adding as middleware

import asyncMiddleware from 'redux-async';
let createStoreWithMiddleware = applyMiddleware(
  asyncMiddleware,
)(createStore);

Usage

// action-creators.js
export const loadUsersForAdmin = adminId => {
  return {
    types: [GET_USERS_REQUEST, GET_USERS_SUCCESS, GET_USERS_FAILURE],
    payload: {
      users: api.getUsersForAdmin(adminId).then(response => response.data.users),
      adminId
    }
  };
}

// reducers.js
import { createReducer } from 'redux-create-reducer';
import { GET_USERS_REQUEST, GET_USERS_SUCCESS, GET_USERS_FAILURE } from '../constants/actions';

const initialState = {};

export default createReducer(initialState, {
  [GET_USERS_REQUEST](state, action) {
    const { adminId } = action.payload;

    return {
      isFetching: true,
      adminId // we always have access to all non promise properties
    };
  },
  [GET_USERS_SUCCESS](state, action) {
    const { adminId, users } = action.payload;

    return {
      isFetching: false,
      users, // all promise properties resolved
      adminId // we always have access to all non promise properties - same as above
    };
  },
  [GET_USERS_FAILURE](state, action) {
    // assert(action.error === true && action.payload instanceof Error);

    // when a property gets rejected then the non promise properties go in the meta object
    // assert(action.meta.adminId);

    return {errorMessage: action.payload.message}; // from Error.prototype.message
  },
});


// smart-container.js
// ... snipped to the middle of the render function
<div>
  {
    !users ?
      <button onClick={() => dispatch(loadUsersForAdmin(localStorage.adminId))}>Load Users</button> :
      (isFetching) ? (<span>isFetching for {adminId}...</span>) : (<pre>{JSON.stringify(users, null, 2)}</pre>)
  }
  { errorMessage && <div className="error">errorMessage</div> }
</div>