0

I am getting the following error: substate is undefined. However, I am not sure why substate would be undefined in my selector. Could someone please help me figure out what might be going wrong?

Selector:

import { createSelector } from 'reselect';

/**
 * Direct selector to the organization state domain
 */
const selectOrganizationDomain = () => (state) => state.get('organization');

/**
 * Other specific selectors
 */


/**
 * Default selector used by organization
 */

const selectOrganization = () => createSelector(
  selectOrganizationDomain(),
  (substate) => substate.toJS()
);

const selectChanges = () => createSelector(
  selectOrganization(),
  (substate) => substate.get('changes')
)

export default selectOrganization;
export {
  selectOrganizationDomain,
  selectChanges
};
Turtle
  • 1,369
  • 1
  • 17
  • 32
  • 3
    Going by the docs, I'm guessing you should pass selectOrganization into createSelector instead of calling it and passing the result of that. – dtanders Dec 30 '16 at 21:09

4 Answers4

1

Your selectOrganizationDomain should be a function that returns .get('organization') on the state:

const selectOrganizationDomain = state => state.get('organization');

Your composed selectors should be the result of the invocation of createSelector, with the other selector functions passed in as arguments to createSelector:

const selectOrganization = createSelector(
  selectOrganizationDomain,
  substate => substate.toJS()
);

const selectChanges = createSelector(
  selectOrganization,
  substate => substate.get('changes')
);
hackerrdave
  • 6,486
  • 1
  • 25
  • 29
  • can you post the code that consumes these selectors? if your `state` is undefined, that's most likely that root of your problems – hackerrdave Dec 30 '16 at 21:22
1

The problem is your .toJS() in selectOrganization. I suppose organization in your state tree is immutable. It transforms your immutable object into a regualr JS object. For a regular object the get function is not defined.

Just get rid of selectOrganization and try selectChanges as:

const selectChanges = () => createSelector(
  selectOrganizationDomain(),
  (substate) => substate.get('changes')
)
Andru
  • 5,954
  • 3
  • 39
  • 56
  • Can you post a screenshot of your state tree as seen when using redux dev tools? – Andru Dec 30 '16 at 21:14
  • I would but due to the error, the page that uses the selector doesn't load – Turtle Dec 30 '16 at 21:15
  • Then please console.log your state in `selectOrganizationDomain`, i.e. `const selectOrganizationDomain = () => (state) => { console.log('organization', state.get('organization')); return state.get('organization'); }` Is organization defined? – Andru Dec 30 '16 at 21:22
1

I think createSelector is expecting you to pass a selctor for the first argument, not the result of calling a selector:

const selectChanges = () => createSelector(
  selectOrganization, // no ()
  (substate) => substate.get('changes')
)
dtanders
  • 1,835
  • 11
  • 13
0

I figured out the problem. In my routes.js, I forgot to inject my reducer/other modules. This was fixed with the following:

{
      path: '/org',
      name: 'organization',
      getComponent(nextState, cb) {
        const importModules = Promise.all([
          System.import('containers/Organization/reducer'),
          System.import('containers/Organization/sagas'),
          System.import('containers/Organization'),
        ]);

        const renderRoute = loadModule(cb);

        importModules.then(([reducer, sagas, component]) => {
          injectReducer('organization', reducer.default);
          injectSagas(sagas.default);
          renderRoute(component);
        });

        importModules.catch(errorLoading);
      },
    },
Turtle
  • 1,369
  • 1
  • 17
  • 32