-
Notifications
You must be signed in to change notification settings - Fork 3
Making API Requests (Resource Actions)
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.
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:
- A resource is
LISTED(requesting ALL users) - A resource is
RECEIVED(requesting a single user) - A resource is
CREATED(creating a new user) - A resource is
UPDATED(updating an already created user) - 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.
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;
Now that the data can be stored from the API, in our component page, we need to:
- Add the Mortar
ResourceActionsto request the data with - Create a resource action for users that the component will trigger
- Add a change listener on the
UsersStore - 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.
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.