Skip to content

Instantly share code, notes, and snippets.

@tmcw
Created July 21, 2015 15:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tmcw/d350d27a462a729db8cb to your computer and use it in GitHub Desktop.
Save tmcw/d350d27a462a729db8cb to your computer and use it in GitHub Desktop.

This is what Mapbox's app is using to load async data within the framework of react-router and flux.

Components are allowed to have fetchData methods like in the async-data example, but those methods are composed into a series of promises that complete in order so that we can load dependent data.

/**
* Certain routes have a `fetchData` static property that defines what
* data they need to be loaded asynchronously _before_ rendering.
*
* This function runs every time that Router.run renders a new RouteHandler.
*
* It looks through all routes that have a `fetchData` property. The
* property is assumed to be a function that takes `params` as an argument
* and returns a Promise.
*
* This chains all of the asynchronous calls: they are run in order
* of nested routes, outside in. What it returns is a Promise that represents
* all of the fetchData promises combined. If one of them fails, they'll
* all fail and this will reject the promise.
*
* If no routes have async data requirements, then the return value of doAsync
* is simply `Promise.resolve(true)`, a promise that immediately resolves
* with the value of `true`.
*
* The values returned by fetchData methods in route handlers are ignored:
* it is assumed that the async work that they do loads data into stores.
*
* This approach is heavily influenced and informed by the react-router
* async data loading example
*
* http://bit.ly/1LgnCGh
*
* @param {Array<Object>} routes an array of react-router nested routes,
* in order from least to most specific
* @param {Object} params the parameters given to the current route
* @param {Object} query the query given to the current route
* @returns {Promise} a promise representing the success or failure
* of all `fetchData` methods run serially in order.
*/
function doAsync(routes, params, query) {
return routes.filter(route => route.handler.fetchData)
.reduce((memo, route) =>
memo.then(route.handler.fetchData.bind(this, params, query)),
Promise.resolve(true));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment