{"id":17905,"library":"redux-logic","title":"Redux Logic Middleware","description":"Redux Logic is a middleware for Redux applications designed to centralize and organize business logic and side effects. It allows developers to intercept actions and perform asynchronous processing, supporting various JavaScript styles including callbacks, Promises, async/await, and Observables (via RxJS). The current stable version is 5.0.2. Release cadence typically involves minor and patch versions for dependency updates and security fixes, with major versions reserved for significant changes like dropping Node.js version support or altering internal event structures. Key differentiators include its declarative API for common side effect patterns (filtering, cancellation, latest request handling, debouncing, throttling), robust testing support via `redux-logic-test`, simplified server-side rendering, and the ability to dynamically load logic for code-splitting scenarios. It aims to provide a flexible alternative to libraries like Redux Saga and Redux Observable by allowing developers to choose their preferred async programming paradigm within a declarative framework.","status":"active","version":"5.0.2","language":"javascript","source_language":"en","source_url":"https://github.com/jeffbski/redux-logic","tags":["javascript","redux","middleware","redux middleware","logic","business logic","domain","domain logic","epic","typescript"],"install":[{"cmd":"npm install redux-logic","lang":"bash","label":"npm"},{"cmd":"yarn add redux-logic","lang":"bash","label":"yarn"},{"cmd":"pnpm add redux-logic","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Redux is a peer dependency and required for `redux-logic` to function as middleware.","package":"redux","optional":false}],"imports":[{"note":"The `createLogic` function defines individual logic units.","wrong":"const createLogic = require('redux-logic').createLogic;","symbol":"createLogic","correct":"import { createLogic } from 'redux-logic';"},{"note":"This factory function creates the Redux middleware that integrates your `redux-logic` instances.","wrong":"const createLogicMiddleware = require('redux-logic').createLogicMiddleware;","symbol":"createLogicMiddleware","correct":"import { createLogicMiddleware } from 'redux-logic';"},{"note":"Import the `Logic` type for TypeScript definitions when creating new logic instances.","symbol":"Logic","correct":"import type { Logic } from 'redux-logic';"}],"quickstart":{"code":"import { createStore, applyMiddleware } from 'redux';\nimport { createLogic, createLogicMiddleware } from 'redux-logic';\nimport axios from 'axios'; // Example dependency, install if needed: npm install axios\n\nconst FETCH_POLLS = 'FETCH_POLLS';\nconst FETCH_POLLS_SUCCESS = 'FETCH_POLLS_SUCCESS';\nconst FETCH_POLLS_FAILED = 'FETCH_POLLS_FAILED';\nconst CANCEL_FETCH_POLLS = 'CANCEL_FETCH_POLLS';\n\n// Reducer\nconst initialState = { polls: [], loading: false, error: null };\nfunction reducer(state = initialState, action) {\n  switch (action.type) {\n    case FETCH_POLLS: return { ...state, loading: true, error: null };\n    case FETCH_POLLS_SUCCESS: return { ...state, loading: false, polls: action.payload };\n    case FETCH_POLLS_FAILED: return { ...state, loading: false, error: action.payload };\n    default: return state;\n  }\n}\n\n// Logic definition\nconst fetchPollsLogic = createLogic({\n  type: FETCH_POLLS,\n  cancelType: CANCEL_FETCH_POLLS,\n  latest: true,\n\n  process({ getState, action }, dispatch, done) {\n    axios\n      .get('https://survey.codewinds.com/polls')\n      .then((resp) => resp.data.polls)\n      .then((polls) => dispatch({ type: FETCH_POLLS_SUCCESS, payload: polls }))\n      .catch((err) => {\n        console.error('Fetch polls error:', err); // Log error\n        dispatch({ type: FETCH_POLLS_FAILED, payload: err.message, error: true });\n      })\n      .then(() => done()); // Always call done when finished\n  }\n});\n\n// Configure middleware and store\nconst logicMiddleware = createLogicMiddleware([fetchPollsLogic]);\nconst store = createStore(reducer, applyMiddleware(logicMiddleware));\n\n// Dispatch an action to trigger the logic\nconsole.log('Dispatching FETCH_POLLS action...');\nstore.dispatch({ type: FETCH_POLLS });\n\n// Optional: Simulate cancellation after a delay\n// setTimeout(() => {\n//   console.log('Dispatching CANCEL_FETCH_POLLS action...');\n//   store.dispatch({ type: CANCEL_FETCH_POLLS });\n// }, 100);\n\n// Listen for state changes (for demonstration)\nconst unsubscribe = store.subscribe(() => {\n  console.log('Current state:', store.getState());\n  if (!store.getState().loading) {\n    unsubscribe(); // Stop listening once loading is complete\n  }\n});\n","lang":"typescript","description":"This quickstart demonstrates how to define and integrate a `redux-logic` unit that fetches data, handles success/failure, and supports cancellation and 'take latest' behavior within a Redux store."},"warnings":[{"fix":"Update `monitor$` handlers to access `err` as an object, e.g., `err.message` for the string, or other properties of the error object.","message":"The `monitor$` notification event handler now signals with the raw error object (`err`) instead of just the error message (`err.message`) if an error was thrown. Code expecting a string should be updated to handle an `Error` object.","severity":"breaking","affected_versions":">=4.0.0"},{"fix":"Upgrade your Node.js runtime to version 8.0.0 or higher. The package.json `engines` field specifies `>=8.0.0`.","message":"Node.js v6 support was dropped in `redux-logic` v3.0.0 due to dependency upgrades. Applications running on Node.js v6 or older will encounter compatibility issues.","severity":"breaking","affected_versions":">=3.0.0"},{"fix":"Ensure that your build pipeline transpiles `redux-logic` (or its UMD output) to ES5 if you need to support older browsers without native ES6 capabilities. For modern browsers or bundler usage, this is generally not an issue.","message":"The UMD build of `redux-logic` is no longer ES5 compatible as of v5.0.0; it now targets ES6. If you are using the UMD build directly in browsers that only support ES5, it will likely break.","severity":"gotcha","affected_versions":">=5.0.0"},{"fix":"This is unlikely to affect most applications. For exceptionally large applications, monitor memory usage and consider refactoring or splitting logic bundles if issues arise.","message":"A 'slight reduction in the number of logics that can be loaded' was noted in v5.0.0 due to updates in the RxJS library. While not an API change, extremely large applications might theoretically hit new internal limits.","severity":"gotcha","affected_versions":">=5.0.0"}],"env_vars":null,"last_verified":"2026-04-23T00:00:00.000Z","next_check":"2026-07-22T00:00:00.000Z","problems":[{"fix":"Install `redux` in your project: `npm install redux` or `yarn add redux`.","cause":"`redux` is a peer dependency of `redux-logic` and must be installed separately.","error":"Error: Cannot find module 'redux'"},{"fix":"Ensure you are using correct import syntax for your module type (e.g., `import { createLogic } from 'redux-logic';` for ESM, or `const { createLogic } = require('redux-logic');` for CJS) and that your bundler/TypeScript configuration is set up correctly for module resolution.","cause":"This error often occurs when trying to `require` an ESM-style export in a CommonJS module, or when a bundler misinterprets the module's export format, or when using an incorrect named import in TypeScript.","error":"TypeError: (0 , redux_logic_1.createLogic) is not a function"},{"fix":"Ensure you call `createLogicMiddleware` with your logic array, like `applyMiddleware(createLogicMiddleware([myLogic]))`, rather than `applyMiddleware(createLogicMiddleware)`.","cause":"The `createLogicMiddleware` function needs to be *called* with an array of logics to return the actual middleware function. If you pass `createLogicMiddleware` itself instead of its return value to `applyMiddleware`, this error will occur.","error":"TypeError: middleware is not a function (when applying middleware)"},{"fix":"Update your `monitor$` handler to properly check if `err` is an `Error` object before accessing its properties, e.g., `error.message` or `error.stack`.","cause":"Since v4.0.0, the `err` object passed to `monitor$` is now the raw `Error` object, not just a string. If your handler expects `err` to be a string and directly accesses `err.message` without checking, this could happen if `err` is not an object or null.","error":"TypeError: Cannot read properties of undefined (reading 'message') in monitor$ handler"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null}