Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to normalize deep nested data in the ngrx/store?

I am using ngrx/store and Angular 6. I have deep nested structure in the store. But i feel like it is not correct way to keep it like this:

const state = [
  {
    aliases: ['alias1', 'alias2'],
    isRequired: false,
    isSensitive: false,
    name: 'Adress',
    timezoneId: 'UTC',
    children: []
  },
  {
    aliases: ['alias3', 'alias4'],
    isRequired: true,
    isSensitive: false,
    name: 'Phone',
    timezoneId: 'UTC-5',
    children: [
      {
        aliases: ['alias1', 'alias2'],
        isRequired: true,
        isSensitive: false,
        name: 'Sub-Phone',
        timezoneId: 'UTC-5',
        children: [
          {
            aliases: ['alias-phone1', 'alias-phone2'],
            isRequired: false,
            isSensitive: true,
            name: 'Sub-Sub-Phone',
            timezoneId: 'UTC',
            children: []
          }
        ]
      }
    ]
  }
]

Here property name is like id, it can't be the same at the same level, but it can in the children. For example Sub-Phone and Sub-Sub-Phone could be named Phone. What is the best way to keep such type of structure in the store that will be easy to change. Because now if want to change name: 'Phone' i should return in reducer full this object with all his children. How i can normalize it?

like image 569
mr__brainwash Avatar asked May 23 '18 11:05

mr__brainwash


3 Answers

A common pattern is to follow this guide, to normalize state shape. Do not nest. Create an id that stores the entities. And then create an id that stores the relations (the children, in you scenario). I have built a sample state for you

const state = {
  objects: {
    id: ['Address', 'Phone', 'Sub-Phone', 'Sub-Sub-Phone'],
    entities: {
      'Address': {
        isRequired: false,
        isSensitive: false,
        timezoneId: 'UTC'
      },
      'Phone': {
        isRequired: true,
        isSensitive: false,
        timezoneId: 'UTC-5'
      },
      'Sub-Phone': {
        isRequired: true,
        isSensitive: false,
        timezoneId: 'UTC-5',
      },
      'Sub-Sub-Phone': {
        isRequired: false,
        isSensitive: true,
        timezoneId: 'UTC',
      }
    }
  },
  children: {
    'Address': [],
    'Phone': ['Sub-Phone'],
    'Sub-Phone': ['Sub-Sub-Phone']
  }
}

Note that the state has 2 levels: one for the objects, one for the children. The objects stores the ids and the entities. The children, store one array for each object key with its children. Note that in ny example there is only one children in the arrays, but you can have something like

'Phone': '['Sub-Phone', 'Sub-Phone2', 'Sub-Phone3']
like image 185
Christian Benseler Avatar answered Sep 23 '22 18:09

Christian Benseler


If you have access to the server implementation, normalization could be done there directly. More likely, however, you are going to normalize the state in the client using a third party library, e.g., normalizr.

There are several articles discussing this topic, for example this one on Hackernoon.

like image 34
tilo Avatar answered Sep 22 '22 18:09

tilo


@ngrx/entity is very neat way to normalize your store. look at this @ngrx/entity ReadMe.

also, it comes with powerful entity adapter and selectors.

like image 36
m.akbari Avatar answered Sep 24 '22 18:09

m.akbari