Skip to content

Making API Requests (Resource Actions)

Kyle Mendes edited this page Feb 16, 2016 · 2 revisions

Requesting Data from an API

Mortar makes requesting data from an external API very easy. By default, Mortar expects that the API will be RESTful, but you can alter it to work with any API with a little work.

The flow for making a request is as follows:

Component -> Resource Action -> API request -> Event Emitted -> Store -> Component

This might seem like a lot of steps just to request data, but it is actually a lot easier than it looks.

Example

Let's say that you're making a page to list all of the users of your application. The first step is to edit the config files so Mortar can find your API. Open up src/config/base-config.<env>.js and edit the baseURL, apiVersion and apiVersionedUrl to point to your API. For example, using the JSONPlaceholder service.

var baseConfig = {
   baseUrl:         'http://jsonplaceholder.typicode.com/',
   apiVersion:      '', // this site doesn't version their api
   apiVersionedUrl: 'http://jsonplaceholder.typicode.com/',
}

Next, let's say we want to users. First, we need to add a store to get the data and store it for retrieval from our components. In src/stores add UsersStore.js Mortar will emit changes when:

  1. A resource is LISTED (requesting ALL users)
  2. A resource is RECEIVED (requesting a single user)
  3. A resource is CREATED (creating a new user)
  4. A resource is UPDATED (updating an already created user)
  5. You can add your own actions by defining them in src/actions/

Since we want to request all users, we only are interested in LISTED right now. So, we can create a new store that will listen for the USERS_LISTED action, retrieve the data, and store it for retrieval by our page.

The Store

var Mortar        = require('../bootstrap').MortarJS; // bootstrap being the file you bootstraped MortarJS in
var ModelStore    = Mortar.Stores.ModelStore;
var AppDispatcher = Mortar.Dispatcher;

/**
 * Data stores
 * @type {Array}
 * @private
 */
// Store for user data
var _users = [];

/**
 * Users store logic
 */
var UserStore = Object.assign({}, ModelStore, {
	getUsers: function () {
		return _users;
	}
});

/**
 * Event Listeners
 */
UsersStore.dispatchToken = AppDispatcher.register(function(action) {
	switch(action.type) {
		case 'USERS_LISTED':
			_user = action.data;
			UsersStore.emitChange();
			
			break;
		default:
		    break;
});

module.exports = UsersStore;

The Page / Component

Now that the data can be stored from the API, in our component page, we need to:

  1. Add the Mortar ResourceActions to request the data with
  2. Create a resource action for users that the component will trigger
  3. Add a change listener on the UsersStore
  4. Bind the data to our page's state when it comes in.

We can add the ResourceActions simply by requiring them.

var ResourceActions = Mortar.Actions.ResourceActions;

Next, we instantiate a new action for to request with.

var UsersList = React.createClass({
    ...
    userAction: new ResourceActions('users'), // matches the endpoint name
    ...
)};

The action will take care of reaching out to the api and making the request for us. All we need to do is listen for the response in our store, and make the request.

The Request

getOptions: { // an object containing the config for our API request
    modifiers: {}, // any modifiers we want, like filters, or includes
	dataNode: 'data' // the key the data is bound to on the response object
},

componentDidMount: function() {
    this.userAction.listResource(this.getOptions); // Request to list all users using our getOptions
    UsersStore.addChangeListener(this.bindResource);
},

componeontWillUnmount: function() {
    UsersStore.removeChangeListener(this.bindResource);
},

bindResource: function() { // Bind the data to state that comes back from the store
    this.setState({
        user: UsersStore.getUsers()
    });
}

And that's it! Our page sent an action to ResourceActions which formed an API request using our base-config and getOptions to send a GET to http://jsonplaceholder.typicode.com/users to ask for every user we have.

Clone this wiki locally