Last active
August 29, 2015 14:22
-
-
Save flatanimals/6820299a897e084b4cd9 to your computer and use it in GitHub Desktop.
[ React / ReactNative / fetch ] extract api calls into reusable package that can be used in both React & ReactNative
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
if (typeof fetch === 'undefined') { | |
console.info("Using Fetch Polyfill"); | |
// Polyfill fetch for clients with no existing fetch implementation | |
// | |
// Uses github's fetch implementation | |
// https://github.com/github/fetch | |
require('whatwg-fetch'); // | |
} | |
else { | |
// This can be removed, but it useful during dev and testing to know if the client natively implements fetch | |
console.info("Using Native Fetch"); | |
} | |
// helper: wrap callback in error aware wrapper | |
function callbackFactory(next) { | |
return function (err, data) { | |
if (typeof err !== 'undefined') { | |
console.error(err, err.response); | |
} | |
next(data) | |
}; | |
} | |
// helper: check response.status for request failure conditions | |
function statusCheck(response) { | |
// Check for that request was successful | |
if (response.status >= 200 && response.status < 300) { | |
return response | |
} | |
// Handler request failure, pass response for client handling and error reporting | |
var errorMsg = 'Api call failed: ' + response.url; | |
var error = new Error(errorMsg); | |
error.response = response; | |
throw error; | |
} | |
// helper: convert fetch response to JSON | |
function toJSON(response) { | |
return response.json() | |
} | |
// Api widget requests | |
function widgets(hostname) { | |
var endpoint = hostname + '/api/widgets'; | |
return { | |
all: function (cb) { | |
fetch(endpoint, { | |
credentials: 'include' // Required to send cookies with the request in Chrome's fetch implementation | |
}) | |
.then(statusCheck) | |
.then(toJSON) | |
.then(function (json) { | |
cb(undefined, json); | |
}) | |
.catch(function (error) { | |
cb(error, undefined) | |
}); | |
} | |
} | |
} | |
// Api factory that configures the api with hostname | |
function ApiFactory (hostname) { | |
if (typeof hostname === 'undefined') { | |
console.warn("api: hostname undefined, falling back to relative url support"); | |
hostname = ''; | |
} | |
return { | |
widgets: widgets(hostname), | |
callbackFactory: callbackFactory | |
} | |
} | |
// export ApiFactory for usage | |
module.exports = ApiFactory |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var React = require('react'); // or var React = require('react-native'); | |
var apiFactory = require('api'); | |
var Api = apiFactory('http://widgets.domain'); // set hostname prefix, could be process.env.HOSTNAME | |
var Widgets = React.createClass({ | |
getInitialState: function () { | |
return { | |
widgets: [] | |
} | |
}, | |
componentDidMount: function () { | |
Api.widgets.all( | |
Api.callbackFactory(data => { | |
this.setState({widgets: data}); | |
}) | |
); | |
}, | |
renderWidget: function (widget) { | |
return <li>{widget.name}</li> | |
}, | |
render: function () { | |
return ( | |
<div> | |
{this.state.widgets.map(this.renderWidget)} | |
</div> | |
) | |
} | |
}); | |
module.exports = Widgets; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment