Actions

Data-fetching tier for Lore

Extending and Overriding Actions

Sometimes you may need to add new actions, or overwrite the blueprints for a specific model. You can do that by creating a custom action inside the src/actions directory. For example, if you wanted to override the createaction for the tweet model, you would create a custom action for tweet/create like this:

src
|-actions
  |-tweet
    |-create.js

When this hook executes, the blueprints for each model are created first, and then the user-defined actions are loaded and merged. This means user-defined actions will always take priority over any actions created by the Lore.

The easiest way to create a new action is often to extract one of the existing actions and then modify the code.

Custom Actions

Custom actions can take two forms; a config object or a function.

Function

The function form is the "norm", and is what is generated when you execute commands likelore extract action tweet/create. A custom action in that form might look like this:

// file: src/actions/tweet/create.js

module.exports = function create(params) {
  return function(dispatch) {
    const model = new lore.models.tweet(params);

    model.save().done(function() {
      dispatch({
        type: ActionTypes.UPDATE_TWEET,
        payload: payload(model, PayloadStates.RESOLVED)
      });
    }).fail(function(response) {
      const error = response.responseJSON;
      dispatch({
        type: ActionTypes.UPDATE_TWEET,
        payload: payload(model, PayloadStates.ERROR_CREATING, error)
      });
    });

    return dispatch({
      type: ActionTypes.ADD_TWEET,
      payload: payload(model, PayloadStates.CREATING)
    });
  };
};

Config Object

In practice, the config object probably isn't that useful, but it does allow you to tailor blueprint behavior for a specific model. For example, when you invoke lore.actions.tweet.create(params) and the API call fails, anUPDATE_TWEETaction is emitted to the Redux store to update the state of the tweet from CREATING toERROR_CREATING.

This flows means that data that failed to be created will still show up in the application. This can be useful if you want to the provide the user with the ability to edit the data and try again, but for some applications you might want any tweets that fail creation to be REMOVED from the Redux store, and disappear from the application.

If you want to do that, the config approach could be a useful approach, and you could use to to change the action emitted on failure from UPDATE_TWEET to REMOVE_TWEET like this:

// file: src/actions/tweet/create.js

module.exports = {
  blueprint: 'create',

  model: lore.models.tweet,

  optimistic: {
    actionType: ActionTypes.ADD_TWEET,
    payloadState: PayloadStates.CREATING
  },

  onSuccess: {
    actionType: ActionTypes.UPDATE_TWEET,
    payloadState: PayloadStates.RESOLVED
  },

  onError: {
    actionType: ActionTypes.REMOVE_TWEET,
    payloadState: PayloadStates.ERROR_CREATING,
    beforeDispatch: function(response, args) {
      lore.log.error('Oh no! The create called failed. Deleting tweet.')
    }
  }
};