Connect

The data-fetching decorator for Lore

all

This blueprint returns a collection of all models in the byCid reducer, and optionally allows you to filter and sort them.

The all blueprint is intended to provide a way to filter and sort reducer data when the intent is to NOT make a server call. For example, in the Quickstart we fetch a page of tweets, and sometimes create new tweets. In this scenario, we know the new tweets are in the store, and we want to display them on top of the paginated tweets.

Without this blueprint, accomplishing that is not straight forward, as it requires you to access the Redux Store directly, get all the data from the byCid reducer, and then filtering and sorting it to get what you want.

With this blueprint, you can skip that process, and provide the filter and sortBy criteria directly to the getState call like this:

Usage

import { connect } from 'lore-hook-connect';
import moment from 'moment';
const timestamp = moment().toISOString();

connect((getState, props) => {
  return {
    tweets: getState('tweet.all', {
      where: function(tweet) {
        return !tweet.id || moment(tweet.data.createdAt).diff(timestamp) > 0
      },
      sortBy: function(tweet) {
        return -moment(tweet.data.createdAt).unix();
      }
    })
  }
})

The getState call above will return all tweets created after the timestamp or that don't have an id (implying that were optimistically created, and should be displayed). The sortBy function then orders the tweets by their createdAt date.

Blueprint

import _ from 'lodash';

export default {

  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) {
    const transformed = _.transform(reducerState, function(result, model) {
      result.push(model);
    }, []);
    const filtered = _.filter(transformed, params.where);
    const sorted = _.sortBy(filtered, params.sortBy);

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

};