Redux API Middleware (Fixed Fork)

raw JSON →
2.0.0 verified Thu Apr 23 auth: no javascript maintenance

redux-api-middleware-fixed is a Redux middleware designed for declarative API calls. It intercepts specific Redux Standard API-calling Actions (RSAAs), identified by a `[CALL_API]` property, and dispatches Flux Standard Actions (FSAs) during the request lifecycle (request, success, failure). This package is a community-maintained fork, currently at version 2.0.0, addressing outstanding pull requests and maintaining the original `redux-api-middleware` codebase. Its primary differentiator is providing a consistent, action-based pattern for managing API side effects within a Redux application, simplifying data fetching and error handling by abstracting away the boilerplate often associated with `fetch` or `axios` calls within Redux thunks or sagas. The release cadence appears infrequent, primarily driven by maintenance needs rather than active feature development.

error TypeError: 'CALL_API' is not a symbol
cause Attempting to use `CALL_API` as a Symbol in an environment or version of the middleware where it's treated as a string, or vice-versa, often due to migration or incorrect import.
fix
Ensure you are importing CALL_API directly from redux-api-middleware-fixed and using it as the action key without attempting to cast it as a Symbol if it's not. For example, [CALL_API]: { ... } is correct.
error Error: Middleware argument must be a function. Expected an object with a 'type' property.
cause This error typically indicates that `redux-api-middleware-fixed` was not correctly applied as a middleware, or that the action dispatched was not a valid RSAA (missing `[CALL_API]` or required properties within it).
fix
Verify that applyMiddleware(apiMiddleware) is correctly set up in your Redux store configuration. Also, double-check that your dispatched action includes [CALL_API] as a property, and that the object assigned to [CALL_API] has endpoint, method, and types properties.
error Unhandled Rejection (TypeError): Failed to fetch
cause The browser's `fetch` API encountered a network error or a CORS issue, and the middleware's internal `fetch` call did not complete successfully.
fix
Check the network tab in browser developer tools for details on the failed request. Common causes include incorrect endpoint URL, network connectivity issues, or missing/misconfigured CORS headers on the API server. Ensure the API endpoint is accessible and correctly configured.
breaking The original `redux-api-middleware` used `Symbol('CALL_API')` as the action key. This 'fixed' fork, specifically around v1.2.0, introduced changes that might treat `CALL_API` as a string instead of a Symbol. While this can simplify serialization, it might break existing code relying on Symbol comparison or strict type checks if migrating from older versions of the original package.
fix Ensure `CALL_API` is imported directly from the package and used as the action key. Avoid hardcoding 'CALL_API' as a string if expecting a Symbol, or vice-versa. Test thoroughly upon upgrade.
gotcha This package is a fork. While it aims to fix issues, it may not receive updates or new features at the same pace as actively maintained alternatives or the original project (if it were still maintained). Long-term maintenance and compatibility with future Redux versions are less certain.
fix Evaluate active alternatives like `redux-thunk`, `redux-saga`, or `redux-observable` for new projects or if long-term support is critical. For existing projects using this, monitor its GitHub for activity.
gotcha The middleware dispatches Flux Standard Actions (FSAs). Ensure your reducers are designed to handle actions with `type`, `payload`, and `error` properties as defined by the FSA specification. Non-FSA compliant actions might lead to unexpected behavior in reducers.
fix Design reducers to specifically handle the `payload` and `error` properties of FSAs. For example, check `action.error` to determine if a failure action was dispatched and access the error object via `action.payload`.
gotcha Error handling for API calls defaults to an `ApiError` object in the `payload` when `error: true` is set. If not handled correctly, UI might not display meaningful error messages or application state might not reflect the error condition.
fix Implement explicit error handling in reducers for failure actions. Access `action.payload` to get the `ApiError` object, which typically contains `status` and `response` properties for detailed error information. Display appropriate user messages based on these details.
npm install redux-api-middleware-fixed
yarn add redux-api-middleware-fixed
pnpm add redux-api-middleware-fixed

Demonstrates setting up a Redux store with `redux-api-middleware-fixed` and dispatching a basic API call action to fetch users.

import { createStore, applyMiddleware, combineReducers } from 'redux';
import { apiMiddleware, CALL_API } from 'redux-api-middleware-fixed';

// A dummy reducer
const dataReducer = (state = { loading: false, users: [], error: null }, action) => {
  switch (action.type) {
    case 'FETCH_USERS_REQUEST':
      return { ...state, loading: true, error: null };
    case 'FETCH_USERS_SUCCESS':
      return { ...state, loading: false, users: action.payload.users };
    case 'FETCH_USERS_FAILURE':
      return { ...state, loading: false, error: action.payload, users: [] };
    default:
      return state;
  }
};

const rootReducer = combineReducers({
  data: dataReducer
});

// Configure the Redux store with apiMiddleware
const store = createStore(rootReducer, applyMiddleware(apiMiddleware));

// Define an API call action
const fetchUsers = () => ({
  [CALL_API]: {
    endpoint: 'https://jsonplaceholder.typicode.com/users',
    method: 'GET',
    types: ['FETCH_USERS_REQUEST', 'FETCH_USERS_SUCCESS', 'FETCH_USERS_FAILURE']
  }
});

// Dispatch the action
store.dispatch(fetchUsers());

// You can subscribe to store changes to see the state updates
const unsubscribe = store.subscribe(() => {
  console.log('Current state:', store.getState().data);
});

// In a real application, you'd typically handle errors and unmount subscriptions
// setTimeout(() => unsubscribe(), 5000);