Skip to main content

Normalizing linear data

reduceFlat action helps to add data from a flat response to the store.

Imagine that a backend returns the next flat shape:

{  "users": [    {      "id": "1",      "firstName": "John",      "lastName": "Smith",      "companyId": "1"    }  ],  "companies": [    {      "id": "1",      "name": "Magic",      "adminId": "2",      "addressId": "1"    }  ],  "addresses": [    {      "id": "1",      "street": "Main st.",      "city": "Town",      "country": "Land"    }  ]}

There is a selector that fetches this data from the store like that: a user with its company and the address of the company.

We only need to specify related bucket names from response as flatKey in selector's meta:

export const selectUser = rootEntity(  selectUserState,  {    // here we go    flatKey: 'users',  },  relatedEntity(    selectCompanyState,    'companyId',    'company',    {      // here we go      flatKey: 'companies',    },    relatedEntity(      selectAddressState,      'addressId',      'address',      {        // here we go        flatKey: 'addresses',      },    ),  ),);

Then the store can be updated by dispatching the reduceFlat action:

// Reduxstore.dispatch(  reduceFlat({    data: response,    selector: selectUser,  }),);
// NGRXthis.store.dispatch(  reduceFlat({    data: response,    selector: selectUser,  }),);// orthis.store.dispatch(  new ReduceFlat(response, selectUser),);

ngrxEntityRelationshipReducer will catch this action, parse the data and put it into the store like that:

const rootState = {  users: {    ids: ['1'],    entities: {      '1': {        id: '1',        firstName: 'John',        lastName: 'Smith',        companyId: '1',      },    },  },  companies: {    ids: ['1'],    entities: {      '1': {        id: '1',        name: 'Magic',        adminId: '2',        addressId: '1',      },    },  },  addresses: {    existingIds: ['1'],    byIds: {      '1': {        id: '1',        street: 'Main st.',        city: 'Town',        country: 'Land',      },    },  },};