{"id":17909,"library":"redux-promise-middleware-actions","title":"Redux Action Creators for Promises","description":"This library provides action creators designed to streamline the creation of synchronous and asynchronous Redux actions, specifically integrating with `redux-promise-middleware`. It is currently stable at version 3.1.0, and while its explicit release cadence is not specified, ongoing build status indicators suggest active maintenance. A key differentiator is its robust first-class TypeScript support, which requires TypeScript 3 or newer for version 3 of the library, and TypeScript 2 for version 1. It simplifies the process of creating async actions by automatically generating `_PENDING`, `_FULFILLED`, and `_REJECTED` actions when a promise is dispatched, thereby eliminating the need for manual action type enums. The library promotes type safety in reducers by allowing action creators to be directly referenced (e.g., `String(myAction)`) and boasts a tiny bundle size, making it a lightweight alternative focused on promise-based Redux flows without external dependencies beyond `redux-promise-middleware` itself.","status":"active","version":"3.1.0","language":"javascript","source_language":"en","source_url":"https://github.com/omichelsen/redux-promise-middleware-actions","tags":["javascript","redux","actions","promise","async","typescript"],"install":[{"cmd":"npm install redux-promise-middleware-actions","lang":"bash","label":"npm"},{"cmd":"yarn add redux-promise-middleware-actions","lang":"bash","label":"yarn"},{"cmd":"pnpm add redux-promise-middleware-actions","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Required for handling the promise lifecycle (pending, fulfilled, rejected) of asynchronous actions created by this library.","package":"redux-promise-middleware","optional":false}],"imports":[{"note":"Used for creating synchronous Redux actions. The library is ESM-first but offers CJS compatibility for older Node.js environments.","wrong":"const createAction = require('redux-promise-middleware-actions').createAction;","symbol":"createAction","correct":"import { createAction } from 'redux-promise-middleware-actions';"},{"note":"The primary function for creating actions with a promise payload, which `redux-promise-middleware` then processes into _PENDING, _FULFILLED, and _REJECTED states.","wrong":"import createAsyncAction from 'redux-promise-middleware-actions';","symbol":"createAsyncAction","correct":"import { createAsyncAction } from 'redux-promise-middleware-actions';"},{"note":"Action creators generated by this library can be cast to a string to get their action type, ensuring type safety and code navigation. This pattern is crucial for TypeScript users.","wrong":"case 'MY_ACTION_FULFILLED': // in a reducer","symbol":"String(actionCreator)","correct":"case String(myActionCreator.fulfilled): // in a reducer"}],"quickstart":{"code":"import { createStore, applyMiddleware, compose } from 'redux';\nimport promiseMiddleware from 'redux-promise-middleware';\nimport { createAsyncAction } from 'redux-promise-middleware-actions';\n\n// 1. Setup Redux store with promiseMiddleware\n// Ensure Redux DevTools compatibility if available\nconst composeEnhancers = (typeof window !== 'undefined' && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__) || compose;\n\n// A simple reducer to handle our async action states\nconst rootReducer = (state = { data: null, loading: false, error: null }, action) => {\n  switch (String(action.type)) { // Use String(action.type) for type matching\n    case String(fetchData.pending): // Action.type for pending actions is usually the base type + _PENDING suffix\n      return { ...state, loading: true, error: null };\n    case String(fetchData.fulfilled): // For fulfilled, payload is the resolved promise value\n      return { ...state, loading: false, data: action.payload };\n    case String(fetchData.rejected): // For rejected, payload is the error object\n      return { ...state, loading: false, error: action.payload };\n    default:\n      return state;\n  }\n};\n\nconst store = createStore(\n  rootReducer,\n  composeEnhancers(applyMiddleware(promiseMiddleware))\n);\n\n// 2. Create an async action\nexport const fetchData = createAsyncAction('FETCH_DATA', async (id) => {\n  // Simulate an asynchronous operation (e.g., an API call)\n  console.log(`Fetching data for ID: ${id}...`);\n  const response = await new Promise(resolve => {\n    setTimeout(() => {\n      if (id === 1) {\n        resolve({ id, value: 'sample data successfully fetched' });\n      } else {\n        throw new Error(`Failed to fetch data for ID: ${id}`);\n      }\n    }, 1000);\n  });\n  return response;\n});\n\n// 3. Dispatch the async action\nconsole.log('--- Dispatching fetchData(1) (success) ---');\nstore.dispatch(fetchData(1));\n\n// Observe state changes over time (for demonstration)\nconst unsubscribe = store.subscribe(() => {\n  console.log('Current state:', store.getState());\n});\n\n// Dispatch another action after a short delay to demonstrate error handling\nsetTimeout(() => {\n  console.log('\\n--- Dispatching fetchData(2) (failure) ---');\n  store.dispatch(fetchData(2));\n}, 3000);\n\n// Clean up subscription after demonstration\nsetTimeout(() => {\n  unsubscribe();\n  console.log('\\nDemonstration complete.');\n}, 5000);\n","lang":"typescript","description":"This quickstart demonstrates how to configure a Redux store with `redux-promise-middleware` and use `redux-promise-middleware-actions` to create and dispatch an asynchronous action, showing how the reducer handles `_PENDING`, `_FULFILLED`, and `_REJECTED` states."},"warnings":[{"fix":"Upgrade your project's TypeScript version to 3.0 or higher, or downgrade `redux-promise-middleware-actions` to a 1.x release compatible with TypeScript 2.x.","message":"Version 3.x of `redux-promise-middleware-actions` requires TypeScript 3.x or newer. For projects using TypeScript 2.x, `redux-promise-middleware-actions` version 1.x must be used.","severity":"breaking","affected_versions":">=3.0.0"},{"fix":"Do not configure `promiseTypeSuffixes` when initializing `redux-promise-middleware` if you are using this library. Rely on the default suffixes provided by `redux-promise-middleware-actions`.","message":"This library is not compatible with the `promiseTypeSuffixes` option of `redux-promise-middleware`. It uses its own fixed `_PENDING`, `_FULFILLED`, `_REJECTED` suffixes.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Ensure both `redux-promise-middleware-actions` and `redux-promise-middleware` are installed (`npm install redux-promise-middleware-actions redux-promise-middleware`) and `promiseMiddleware` is applied using `applyMiddleware` when creating your Redux store.","message":"`redux-promise-middleware-actions` requires `redux-promise-middleware` to be installed and applied to the Redux store's middleware chain to correctly handle asynchronous actions.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-23T00:00:00.000Z","next_check":"2026-07-22T00:00:00.000Z","problems":[{"fix":"In reducers, always use `String(actionCreator)` or `actionCreator.toString()` to obtain the action type string, ensuring type compatibility and leverage TypeScript's type inference.","cause":"Attempting to use a plain string literal as an action type in a reducer when `String(actionCreator)` is expected for type safety.","error":"Argument of type 'string' is not assignable to parameter of type 'AnyAction'."},{"fix":"Ensure that action creators meant to handle promises and their lifecycle states are created using `createAsyncAction`.","cause":"Trying to access `.pending`, `.fulfilled`, or `.rejected` properties on an action creator created with `createAction` (synchronous) instead of `createAsyncAction`.","error":"TypeError: Cannot read properties of undefined (reading 'pending')"},{"fix":"Always reject promises with instances of `Error` (e.g., `Promise.reject(new Error('Failed!'))`). Alternatively, configure `redux-promise-middleware`'s `isError` option to handle custom error types.","cause":"`redux-promise-middleware` by default expects promise rejections to be `Error` objects to set `action.error: true` for `_REJECTED` actions.","error":"Promise rejected with a non-error: 'Your error message here'. Consider rejecting with an Error object to ensure `action.error` is true."}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null}