React
Performing HTTP Requests with Custom Middleware
  •  

Creating Promise Middleware

PRO
Outline

The first thing we'll do is integrate our agent file with the Home component:

Integrate with Home component

components/Home/index.js

import Banner from './Banner';
import MainView from './MainView';
import React from 'react';
import agent from '../../agent';
import { connect } from 'react-redux';

+ const Promise = global.Promise;

const mapStateToProps = state => ({
  appName: state.appName
});

+ const mapDispatchToProps = dispatch => ({
+  onLoad: (payload) =>
+   dispatch({ type: 'HOME_PAGE_LOADED', payload }),
+ });

class Home extends React.Component {
+ componentWillMount() {
+   this.props.onLoad(agent.Articles.all());
+ }

  render() {
    // ...
  }
}

- export default connect(mapStateToProps, () => ({}))(Home); 
+ export default connect(mapStateToProps, mapDispatchToProps)(Home);

This mapDispatchToProps function is the second function that gets passed to connect(). This function maps the Redux store's dispatch() to other functions. Each function that mapDispatchToProps() returns gets attached to the component's props. This means your component can call this.props.onLoad() to fire off an event with type 'HOME_PAGE_LOADED' and a 'payload', which is the Promise from our request.

We'll tap into one of React's lifecycle hooks using componentWillMount(). This function is invoked immediately before the component is rendered making it a great place for our HTTP articles request.

Now we're dispatching an action that has a 'payload' property that contains a promise. Middleware allows us to intercept and transform actions, and we're going to create our own to intercept actions whose payload property is a promise.

Create a middleware.js file and build out the middleware.

Build out the promise middleware

src/middleware.js

const promiseMiddleware = store => next => action => {
  if (isPromise(action.payload)) {
    action.payload.then(
      res => {
        action.payload = res;
        store.dispatch(action);
      },
      error => {
        action.error = true;
        action.payload = error.response.body;
        store.dispatch(action);
      }
    );

    return;
  }

  next(action);
};

function isPromise(v) {
  return v && typeof v.then === 'function';
}

export {
  promiseMiddleware
};

Now you need to plug this middleware into the redux store. Back in index.js, let's use this applyMiddleware function that redux exports to plug the promise middleware into redux.

Apply the promise middleware to our store
import App from './components/App';
import { Provider } from 'react-redux';
import ReactDOM from 'react-dom';
import React from 'react';
import { applyMiddleware, createStore } from 'redux';
+ import { promiseMiddleware } from './middleware';

const defaultState = {
  // ...
};
const reducer = function(state = defaultState, action) {
  // ...
};
- const store = createStore(reducer);
+ const store = createStore(reducer, applyMiddleware(promiseMiddleware));

// ...
 

I finished! On to the next chapter