1.6.1 • Published 6 years ago

redux-modular-models v1.6.1

Weekly downloads
1
License
MIT
Repository
-
Last release
6 years ago

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],
          },
        },
      },
    });
  });
});
1.6.1

6 years ago

1.6.0

7 years ago

1.5.0

7 years ago

1.4.2

7 years ago

1.4.1

7 years ago

1.4.0

7 years ago

1.3.0

7 years ago

1.2.5

7 years ago

1.2.4

7 years ago

1.2.3

7 years ago

1.2.1

7 years ago

1.2.0

7 years ago

1.1.3

7 years ago

1.1.2

7 years ago

1.1.1

7 years ago

1.1.0

7 years ago

1.0.0

7 years ago