Features

Key features that make up the main value proposition for Lore

Visual Cues

Useful for providing the user with a visual indication that some action is being performed but has no yet completed. Examples include fetching, updating and creating data.

Visualization

This video demonstrates what visual cues look like. Screenshots are from the Simply Social prototype that Invision provides you when you sign up for an account.

Usage

This section demonstrates how to use the data structure provided by Lore so please read that first if you're unfamiliar with the data structure.

Data can go through a lot of different states during the lifecycle of an application. Lore calls these statesPayloadStates, after the payload field in the actions dispatched to the Redux store, and accounts for the following scenarios by default:

  • Data being fetched
  • Data being created
  • Data being updated
  • Data being deleted

It also accounts for error conditions on each of those scenarios:

  • Error while fetching data
  • Error while creating data
  • Error while updating data
  • Error while deleting data

And finally it accounts for the scenario where nothing is happening to data, after the transient state has been resolved. All of these scenarios are represented as constants in a file called PayloadStates atsrc/constants/PayloadStates.js in your project. That file looks like this:

PayloadStates = {
  RESOLVED: 'RESOLVED',

  CREATING: 'CREATING',
  UPDATING: 'UPDATING',
  DELETING: 'DELETING',
  FETCHING: 'FETCHING',

  ERROR_CREATING: 'ERROR_CREATING',
  ERROR_UPDATING: 'ERROR_UPDATING',
  ERROR_DELETING: 'ERROR_DELETING',
  ERROR_FETCHING: 'ERROR_FETCHING'
}

When you need to communicate the state of data to your user, you can do it by comparing the state property of the data to one of the payload states and changing what you render according. I'll list the main scenarios below:


Resolved

This is the static state of data, when it exists and is not being acted upon. An example post might look like this:

post = {
  id: 1,
  cid: 'c1',
  state: 'RESOLVED',
  data: {
    id: 1,
    title: 'Cornbread is Yummy'
  },
  error: {}
}

The fact that id has a value tells us this resource exists on the server. And the state is set to RESOLVED to signify that this resource is not being modified or deleted.

You can also think of resolved resources as the default rendering state, like this:

createReactClass({
  displayName: 'Post',

  propTypes: {
    post: React.PropTypes.object.isRequired
  },

  render: function() {
    var post = this.props.post;

    return (
      <div key={post.id} className="post">
        {post.data.title}
      </div>
    );
  }
})

Creating

An example post for a resource being created might look like this:

post = {
  id: undefined,
  cid: 'c1',
  state: 'CREATING',
  data: {
    title: 'Cornbread is Yummy'
  },
  error: {}
}

The id is undefined because the resource doesn't exist on the server yet. The data field contains whatever properties were sent to the server. And the state is set to CREATING to signify that this resource is in the process of being created.

When rendering a resource being created, it's recommended that you modifying the styling or content of the component to provide a visual indication of this state to the user. If you're rendering a list of components and need to keyto avoid React warnings you can use the cid property.

createReactClass({

  propTypes: {
    posts: React.PropTypes.object.isRequired
  },

  render: function() {
    var posts = this.props.posts;

    if (posts.state === PayloadStates.CREATING) {
      return (
        <div key={post.cid} className="post creating">
          {post.data.title}
        </div>
      );
    }

    // todo: render RESOLVED state
  }
});

Updating

An example post for a resource being updated might look like this:

post = {
  id: 1,
  cid: 'c1',
  state: 'UPDATING',
  data: {
    id: 1,
    title: 'Cornbread is SUPER Yummy'
  },
  error: {}
}

The data field contains whatever properties were sent to the server, and the state is set to UPDATING to signify that this resource is in the process of being updated.

When rendering a resource being updated, it's recommended that you modifying the styling or content of the component to provide a visual indication of this state to the user.

createReactClass({

  propTypes: {
    posts: React.PropTypes.object.isRequired
  },

  render: function() {
    var posts = this.props.posts;

    if (posts.state === PayloadStates.UPDATING) {
      return (
        <div key={post.id} className="post updating">
          {post.data.title}
        </div>
      );
    }

    // todo: render RESOLVED state
  }
});

Deleting

An example post for a resource being deleted might look like this:

post = {
  id: 1,
  cid: 'c1',
  state: 'DELETING',
  data: {
    id: 1,
    title: 'Cornbread is Yummy'
  },
  error: {}
}

The state is set to DELETING to signify that this resource is in the process of being deleted.

When rendering a resource being deleting, it's recommended that you modifying the styling or content of the component to provide a visual indication of this state to the user.

createReactClass({

  propTypes: {
    posts: React.PropTypes.object.isRequired
  },

  render: function() {
    var posts = this.props.posts;

    if (posts.state === PayloadStates.DELETING) {
      return (
        <div key={post.id} className="post deleting">
          {post.data.title}
        </div>
      );
    }

    // todo: render RESOLVED state
  }
});

Fetching

An example post for a resource being fetched might look like this:

post = {
  id: 1,
  cid: 'c1',
  state: 'FETCHING',
  data: {},
  error: {}
}

The data field is empty because the server's response is used to populate it, and all we know right now is the idof the resource we want to fetch. The state is set to FETCHING to signify that this resource is in the process of being fetched.

When rendering a resource being fetched, it's recommended that you modifying the styling or content of the application to provide a visual indication of this state to the user.

createReactClass({

  propTypes: {
    posts: React.PropTypes.object.isRequired
  },

  render: function() {
    var posts = this.props.posts;

    if (posts.state === PayloadStates.FETCHING) {
      return (
        <div>
          Loading post...
        </div>
      );
    }

    // todo: render RESOLVED state
  }
});

Error Creating

When there is an error creating a resource the data structure might look like this:

post = {
  id: undefined,
  cid: 'c1',
  state: 'ERROR_CREATING',
  data: {
    title: 'Cornbread is Yummy'
  },
  error: {
    statusCode: 409,
    message: 'Title already exists'
  }
}

The state will be updated to ERROR_CREATING, letting us know that we were trying to create this resource but something went wrong. The error field will be populated with whatever error message the server communicates back.

When rendering a resource with an error, it's recommended that you modifying the styling or content of the component to provide a visual indication of this state to the user.

createReactClass({

  propTypes: {
    posts: React.PropTypes.object.isRequired
  },

  render: function() {
    var posts = this.props.posts;

    if (posts.state === PayloadStates.ERROR_CREATING) {
      return (
        <div key={post.cid} className="post">
          <span className="error">
            {post.error.message}
          </span>
          {post.data.title}
        </div>
      );
    }

    // todo: render RESOLVED state
  }
});

Error Updating

When there is an error creating a resource the data structure might look like this:

post = {
  id: 1,
  cid: 'c1',
  state: 'ERROR_UPDATING',
  data: {
    id: 1,
    title: 'Cornbread is SUPER Yummy'
  },
  error: {
    statusCode: 409,
    message: 'Title already exists'
  }
}

The state will be updated to ERROR_UPDATING, letting us know that we were trying to update this resource but something went wrong. The error field will be populated with whatever error message the server communicates back.

When rendering a resource with an error, it's recommended that you modifying the styling or content of the component to provide a visual indication of this state to the user.

createReactClass({

  propTypes: {
    posts: React.PropTypes.object.isRequired
  },

  render: function() {
    var posts = this.props.posts;

    if (posts.state === PayloadStates.ERROR_UPDATING) {
      return (
        <div key={post.id} className="post">
          <span className="error">
            {post.error.message}
          </span>
          {post.data.title}
        </div>
      );
    }

    // todo: render RESOLVED state
  }
});

Error Deleting

When there is an error creating a resource the data structure might look like this:

post = {
  id: 1,
  cid: 'c1',
  state: 'ERROR_DELETING',
  data: {
    id: 1,
    title: 'Cornbread is SUPER Yummy'
  },
  error: {
    statusCode: 403,
    message: 'Not authorized'
  }
}

The state will be updated to ERROR_DELETING, letting us know that we were trying to delete this resource but something went wrong. The error field will be populated with whatever error message the server communicates back.

When rendering a resource with an error, it's recommended that you modifying the styling or content of the component to provide a visual indication of this state to the user.

createReactClass({

  propTypes: {
    posts: React.PropTypes.object.isRequired
  },

  render: function() {
    var posts = this.props.posts;

    if (posts.state === PayloadStates.ERROR_DELETING) {
      return (
        <div key={post.id} className="post">
          <span className="error">
            {post.error.message}
          </span>
          {post.data.title}
        </div>
      );
    }

    // todo: render RESOLVED state
  }
});

Error Fetching

When there is an error creating a resource the data structure might look like this:

post = {
  id: 1,
  cid: 'c1',
  state: 'ERROR_FETCHING',
  data: {},
  error: {
    statusCode: 403,
    message: 'Not authorized'
  }
}

The state will be updated to ERROR_FETCHING, letting us know that we were trying to fetch this resource but something went wrong. The error field will be populated with whatever error message the server communicates back.

When rendering a resource with an error, it's recommended that you modifying the styling or content of the component to provide a visual indication of this state to the user.

createReactClass({

  propTypes: {
    posts: React.PropTypes.object.isRequired
  },

  render: function() {
    var posts = this.props.posts;

    if (posts.state === PayloadStates.ERROR_FETCHING) {
      return (
        <div className="error">
          Error fetching post :(
        </div>
      );
    }

    // todo: render RESOLVED state
  }
});