Redux Action Validator Middleware

raw JSON →
0.2.3 verified Thu Apr 23 auth: no javascript abandoned

redux-validator is a middleware for Redux that enables validation of action parameters before they reach the reducers. It works by inspecting the `meta.validator` field of a dispatched action, which defines validation functions and messages for properties within the `action.payload`. If any validation fails, the dispatch is aborted, and an error object containing the `err`, `msg`, `param`, and `id` of the failed validation is returned. The library is compatible with Flux Standard Actions (FSA). As of the provided information, the current version is 0.2.3, suggesting it may be an early-stage or unmaintained project with no active release cadence. Its primary differentiator is the direct integration of validation rules within the action's `meta` field, offering a localized approach to action-specific data integrity checks.

error { err: 'validator', msg: 'Cannot add an empty todo', param: 'text', id: 0 }
cause An action was dispatched where one or more validation functions defined in `action.meta.validator` returned `false` for a corresponding `action.payload` property.
fix
Examine the msg and param fields in the returned error object to identify the specific validation failure. Adjust the action's payload data to meet the defined validation criteria before dispatching.
error Error: Actions may not have an undefined 'type' property.
cause The `redux-validator` middleware might be incorrectly ordered, leading to an action being dispatched or modified by another middleware before validation, resulting in an unexpected action shape or an aborted dispatch that doesn't return the expected error object.
fix
Ensure that redux-validator is the very first middleware in your applyMiddleware call. This allows it to inspect and potentially abort the dispatch before other middlewares process or expect a fully valid action.
gotcha It is crucial to apply `redux-validator` as the *first* middleware in your `applyMiddleware` chain. Placing it after other middleware that might modify the action could lead to unexpected validation behavior or errors, as the validator expects the original action shape.
fix Ensure `validator` is the first argument passed to `applyMiddleware`, e.g., `applyMiddleware(validator, otherMiddleware)`.
gotcha The library is in a very early development state (version 0.2.3). This might imply a lack of active maintenance, potential for unpatched bugs, or incomplete features. Consider its stability and long-term support before relying on it for production applications.
fix Review the GitHub repository for recent activity (commits, issues) to assess its current maintenance status. For critical applications, consider more actively maintained alternatives or be prepared to contribute to its development.
npm install redux-validator
yarn add redux-validator
pnpm add redux-validator

This quickstart demonstrates how to set up `redux-validator` middleware and define validation rules within an action's `meta` field. It shows both successful and aborted dispatches based on validation outcomes.

import { createStore, applyMiddleware } from 'redux';
import Validator from 'redux-validator';

// A dummy reducer for the example
const reducer = (state = { todos: [] }, action) => {
  switch (action.type) {
    case 'ADD_TODO':
      return { ...state, todos: [...state.todos, action.payload] };
    default:
      return state;
  }
};

// Initialize the validator middleware
const validator = Validator();

// Apply middleware, ensure validator is applied first for correctness
const createStoreWithMiddleware = applyMiddleware(validator)(createStore);
const store = createStoreWithMiddleware(reducer);

// Example valid action
const validAction = {
  type: 'ADD_TODO',
  payload: {
    text: 'Learn redux-validator',
    complete: false
  },
  meta: {
    validator: {
      text: {
        func: (text, state, payload) => typeof text === 'string' && text.length > 0,
        msg: 'Todo text cannot be empty'
      },
      complete: {
        func: (complete, state, payload) => typeof complete === 'boolean',
        msg: 'Complete status must be a boolean'
      }
    }
  }
};

const result1 = store.dispatch(validAction);
console.log('Dispatch result (valid):', result1);
console.log('Current state (after valid):', store.getState());

// Example invalid action
const invalidAction = {
  type: 'ADD_TODO',
  payload: {
    text: '', // Invalid: empty string
    complete: 'no' // Invalid: not a boolean
  },
  meta: {
    validator: {
      text: {
        func: (text, state, payload) => typeof text === 'string' && text.length > 0,
        msg: 'Todo text cannot be empty'
      },
      complete: {
        func: (complete, state, payload) => typeof complete === 'boolean',
        msg: 'Complete status must be a boolean'
      }
    }
  }
};

const result2 = store.dispatch(invalidAction);
console.log('Dispatch result (invalid):', result2);
console.log('Current state (after invalid - should be same as before):', store.getState());