redux-modular-models

1.6.1 • Public • Published

redux-modular-models

Manage models state for CRUD with ease.

Installation

yarn add redux-modular-models

Usage Example

The store should know how to handle actions. To enable this, we need to create the modelReducer to your store. It serves for all of your models, so you only have to pass it once.

Create model reducer and update state with actions

import { createStore, combineReducers } from 'redux';
import { schema } from 'normalizr';
 
import {
  createReducer,
  arrayRemoveAll,
  arrayConcat,
  entityMerge,
} from '../src/index';
 
describe('can createReducer and update state with actions', () => {
  const options = { idAttribute: 'objectId' };
  const userSchema = new schema.Entity('user', {}, options);
  const itemSchema = new schema.Entity('item', { user: userSchema }, options);
  const collectionSchema = new schema.Entity(
    'collection',
    { user: userSchema },
    options,
  );
 
  const rootReducer = combineReducers({
    models: createReducer({
      models: [
        {
          name: 'user',
          schema: userSchema,
        },
        {
          name: 'item',
          initialState: {
            entities: {
              '1': {
                objectId: 1,
                title: 'item1',
              },
            },
            arrays: {
              all: [1],
            },
          },
          schema: itemSchema,
        },
        {
          name: 'collection',
          schema: collectionSchema,
        },
      ],
    }),
  });
  const store = createStore(rootReducer);
 
  test('initialState', () => {
    const { getState } = store;
    expect(getState()).toEqual({
      models: {
        user: {
          entities: {},
          arrays: {
            all: [],
          },
          schemas: {
            entity: userSchema,
            array: [userSchema],
          },
        },
        item: {
          entities: {
            '1': {
              objectId: 1,
              title: 'item1',
            },
          },
          arrays: {
            all: [1],
          },
          schemas: {
            entity: itemSchema,
            array: [itemSchema],
          },
        },
        collection: {
          entities: {},
          arrays: {
            all: [],
          },
          schemas: {
            entity: collectionSchema,
            array: [collectionSchema],
          },
        },
      },
    });
  });
 
  test('arrayRemoveAll', () => {
    const { dispatch, getState } = store;
    dispatch(arrayRemoveAll('item', 'all'));
    expect(getState()).toEqual({
      models: {
        user: {
          entities: {},
          arrays: {
            all: [],
          },
          schemas: {
            entity: userSchema,
            array: [userSchema],
          },
        },
        item: {
          entities: {
            '1': {
              objectId: 1,
              title: 'item1',
            },
          },
          arrays: {
            all: [],
          },
          schemas: {
            entity: itemSchema,
            array: [itemSchema],
          },
        },
        collection: {
          entities: {},
          arrays: {
            all: [],
          },
          schemas: {
            entity: collectionSchema,
            array: [collectionSchema],
          },
        },
      },
    });
  });
 
  test('arrayConcat with reset', () => {
    const { dispatch, getState } = store;
    const data = [
      { objectId: 1, title: 'item1', user: { objectId: 1, name: 'Bob Wei' } },
      { objectId: 2, title: 'item2' },
    ];
    dispatch(arrayConcat(data, 'item', 'all', { reset: true }));
    expect(getState()).toEqual({
      models: {
        user: {
          entities: {
            '1': { objectId: 1, name: 'Bob Wei' },
          },
          arrays: {
            all: [],
          },
          schemas: {
            entity: userSchema,
            array: [userSchema],
          },
        },
        item: {
          entities: {
            '1': {
              objectId: 1,
              title: 'item1',
              user: 1,
            },
            '2': { objectId: 2, title: 'item2' },
          },
          arrays: {
            all: [1, 2],
          },
          schemas: {
            entity: itemSchema,
            array: [itemSchema],
          },
        },
        collection: {
          entities: {},
          arrays: {
            all: [],
          },
          schemas: {
            entity: collectionSchema,
            array: [collectionSchema],
          },
        },
      },
    });
  });
 
  test('arrayConcat', () => {
    const { dispatch, getState } = store;
    const data = [
      { objectId: 1, title: 'item1', user: { objectId: 1, name: 'Bob Wei' } },
      { objectId: 2, title: 'item2' },
    ];
    dispatch(arrayConcat(data, 'item', 'all'));
    expect(getState()).toEqual({
      models: {
        user: {
          entities: {
            '1': { objectId: 1, name: 'Bob Wei' },
          },
          arrays: {
            all: [],
          },
          schemas: {
            entity: userSchema,
            array: [userSchema],
          },
        },
        item: {
          entities: {
            '1': {
              objectId: 1,
              title: 'item1',
              user: 1,
            },
            '2': { objectId: 2, title: 'item2' },
          },
          arrays: {
            all: [1, 2, 1, 2],
          },
          schemas: {
            entity: itemSchema,
            array: [itemSchema],
          },
        },
        collection: {
          entities: {},
          arrays: {
            all: [],
          },
          schemas: {
            entity: collectionSchema,
            array: [collectionSchema],
          },
        },
      },
    });
  });
 
  test('entityMerge for update', () => {
    const { dispatch, getState } = store;
    dispatch(entityMerge({ objectId: 1, title: 'Hello World' }, 'item'));
    expect(getState()).toEqual({
      models: {
        user: {
          entities: {
            '1': { objectId: 1, name: 'Bob Wei' },
          },
          arrays: {
            all: [],
          },
          schemas: {
            entity: userSchema,
            array: [userSchema],
          },
        },
        item: {
          entities: {
            '1': {
              objectId: 1,
              title: 'Hello World',
              user: 1,
            },
            '2': { objectId: 2, title: 'item2' },
          },
          arrays: {
            all: [1, 2, 1, 2],
          },
          schemas: {
            entity: itemSchema,
            array: [itemSchema],
          },
        },
        collection: {
          entities: {},
          arrays: {
            all: [],
          },
          schemas: {
            entity: collectionSchema,
            array: [collectionSchema],
          },
        },
      },
    });
  });
 
  test('entityMerge for insert', () => {
    const { dispatch, getState } = store;
    dispatch(entityMerge({ objectId: 3, title: 'item3' }, 'item'));
    expect(getState()).toEqual({
      models: {
        user: {
          entities: {
            '1': { objectId: 1, name: 'Bob Wei' },
          },
          arrays: {
            all: [],
          },
          schemas: {
            entity: userSchema,
            array: [userSchema],
          },
        },
        item: {
          entities: {
            '1': {
              objectId: 1,
              title: 'Hello World',
              user: 1,
            },
            '2': { objectId: 2, title: 'item2' },
            '3': { objectId: 3, title: 'item3' },
          },
          arrays: {
            all: [1, 2, 1, 2],
          },
          schemas: {
            entity: itemSchema,
            array: [itemSchema],
          },
        },
        collection: {
          entities: {},
          arrays: {
            all: [],
          },
          schemas: {
            entity: collectionSchema,
            array: [collectionSchema],
          },
        },
      },
    });
  });
});
 

Dependents (0)

Package Sidebar

Install

npm i redux-modular-models

Weekly Downloads

2

Version

1.6.1

License

MIT

Unpacked Size

236 kB

Total Files

12

Last publish

Collaborators

  • bobwpy