Redux: Best practise of handling normalised Entities?

Created on 19 Aug 2015  ·  3Comments  ·  Source: reduxjs/redux

In my first App with Redux, I am trying to keep my collections normalised as recommended. This way you only have to change the Entities in one place. (this feels right to me)

At first i successfully normalised my Array of data to an Array-like-Object of Entities with the id's as key's

Then i wanted to list the entities in a View, so i had to parse it back to an Array. Also if i want to filter my Entities, i need the real Array. Is this really the right approach?

Example with re-select:

    // As "id" for my images i use "uri"

    imageEntities = {
     uri1: {image...},
     uri2: {image...},
    ....
    }

    // Selectors:
    const imagesSelector = state => state.images;

    // parse the Array-like-Object to an Array
    const imagesArySelector = createSelector(
      [imagesSelector],
          images => {
            let ary = [];
            for (var key in images) {
              if (images.hasOwnProperty(key)) {
                ary.push(images[key]);
              }
             }
            return ary;
          }
     );

    // filter the Array to get only the new images
    export const newImagesSelector = createSelector(
      [imagesArySelector],
        images => images.filter(image => image.isNew)
     );

Is this really the right approach? (it is working fine, from what i see until now)

question

Most helpful comment

I think it can be done more elegantly.
How I do it:

import { createSelector } from 'reselect';

const providersSelector = state => state.entities.providers;
const subscribersSelector = state => state.entities.subscribers;

export const providersArraySelector = createSelector(
    [providersSelector],
    providers => Object.keys(providers).map(id => providers[id])
);

export const subscribersArraySelector = createSelector(
    [subscribersSelector],
    subscribers => Object.keys(subscribers).map(id => subscribers[id])
);

All 3 comments

I think it can be done more elegantly.
How I do it:

import { createSelector } from 'reselect';

const providersSelector = state => state.entities.providers;
const subscribersSelector = state => state.entities.subscribers;

export const providersArraySelector = createSelector(
    [providersSelector],
    providers => Object.keys(providers).map(id => providers[id])
);

export const subscribersArraySelector = createSelector(
    [subscribersSelector],
    subscribers => Object.keys(subscribers).map(id => subscribers[id])
);

@itsmepetrov looks a'lot better... thx.

So in principle I am on the right track. Anybody else?

Then i wanted to list the entities in a View, so i had to parse it back to an Array.

You can keep an array of IDs when arrays are more convenient to work with. You'll _need_ to do this for things like pagination. The real-world example in examples folder does that.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ilearnio picture ilearnio  ·  3Comments

dmitry-zaets picture dmitry-zaets  ·  3Comments

timdorr picture timdorr  ·  3Comments

ramakay picture ramakay  ·  3Comments

jimbolla picture jimbolla  ·  3Comments