Connect

The data-fetching decorator for Lore

Extending or Overriding Blueprints

This section explains how to create your own blueprints.

Blueprint Structure

All blueprints are a template that describe how to convert the arguments in the getState method call to a reducer lookup and an action call.

You have no control over the template itself (without creating a custom lore-hook-connect hook), but you have complete control over the steps within each the template.

This is the structure of a template.

export default {

  defaults: {
    // default arguments you want provided to all getState calls for this blueprint
  },

  verifyParams: function(params) {
    // determines whether the parameters passed to the getState call are valid
  },

  getReducerState: function(storeState) {
    // gets the subset of the store state we are interested in
  },

  getPayload: function(reducerState, params) {
    // gets the piece of data in the subset of the store state we want
  },

  callAction: function(action, params) {
    // controls how the action gets called
  }

}

Usage

To illustrate the interface, let's take a look at how you could add the all blueprint yourself.

First, you need to define the blueprint in the config/connect.js file like this:

// config/connect.js
import _ from 'lodash';

export default {

  blueprints: {
    all: {
      defaults: {
        where: function(model) {
          return true;
        },
        sortBy: function(model) {
          return true;
        }
      },

      verifyParams: function(params) {
        if (!_.isFunction(params.where)) {
          throw new Error("The 'where' field must be a function");
        }

        if (!_.isFunction(params.sortBy)) {
          throw new Error("The 'sortBy' field must be a function");
        }
      },

      getAction: function(actions) {
        // no op
      },

      getPayload: function(reducerState, params) {
        var data = _
          .chain(reducerState)
          .transform(function(result, model) {
            result.push(model);
          }, [])
          .filter(params.where)
          .sortBy(params.sortBy)
          .value();

        return {
          state: 'RESOLVED',
          data: data
        };
      }
    }
  }
};

This blueprint defines two default parameters, where and sortBy, has no action, and iterates through the provided reducerState, filtering and sorting the results, which are then returned in a data structure with the state always set to RESOLVED (since it makes no server calls, the state is never transient).

Next, you need to tell lore how to use it. To do that, we need to define a reducerActionMap, and we can use the new * syntax to say "this mapping applies to all models".

// config/connect.js
export default {
  blueprints: {
    all: {
      // ... definition
    }
  },

  reducerActionMap: {
    '*.all': {
      action: null,
      reducer: '*.byCid',
      blueprint: 'filter'
    }
  }

};

That's it! With those two changes, you can easily extend and override the behavior of the connect function and associated getState calls.