Skip to content

Instantly share code, notes, and snippets.

@evanrs
Last active September 14, 2019 17:55
Show Gist options
  • Save evanrs/3f2cd89ac99cfee37d11 to your computer and use it in GitHub Desktop.
Save evanrs/3f2cd89ac99cfee37d11 to your computer and use it in GitHub Desktop.
React WaitOn component
const Promise = require('bluebird');
const React = require('react');
const superagent = require('superagent');
const assign = require('lodash/object/assign');
const isArray = require('lodash/lang/isArray');
const isFunction = require('lodash/lang/isFunction');
const isObject = require('lodash/lang/isArray');
const isString = require('lodash/lang/isString');
const log = require('debug')('component:await');
class Await extends React.Component {
static propTypes = {
handler: React.PropTypes.func,
render: React.PropTypes.func,
resolve: React.PropTypes.oneOfType([
// Promise
React.PropTypes.objectOf({
then: React.PropTypes.func,
catch: React.PropTypes.func
}),
// URL
React.PropTypes.string,
]),
then: React.PropTypes.func,
// Deprecating
url: React.PropTypes.string,
}
static defaultProps = {
then: data => data,
render: data => (
<pre style={{lineHeight: '12px'}}>
<code style={{fontSize: 12}}>
{JSON.stringify(data, null, 4)}
</code>
</pre>
)
}
componentWillMount() {
this.props.url &&
console.warn('Use of url prop with <Await/> is deprecated.', this.props.url);
this.setState({
request: Await._whenRequest(this.props.resolve || this.props.url)
});
}
componentDidMount() {
this.state.request.
then(data => this.props.then(data)).
then(data => this.setState({data})).
catch(error => this.setState({error}));
}
render() {
const {request, data} = this.state;
const {handler, render, loader, ...props} = this.props;
return (
request.isFulfilled() ?
isFunction(handler) ?
React.createElement(handler, {...props, data})
: render(data)
: loader === true ?
<div className='relay'>
<div className='relay-loader'>
{request.isPending() ?
'Loading...'
: `Error: ${this.state.error && this.state.error.message}`}
</div>
</div>
: <span>{loader || ''}</span>
)
}
static _requests = {}
static _whenRequest (url) {
let promise;
if (isArray(url)) {
promise =
Promise.all(url.map(url => this._whenRequest(url)))
}
else if (isString(url)) {
promise =
this._requests[url] =
this._requests[url] || new Promise((resolve, reject) => (
superagent.
get(url).
withCredentials().
set('Accept', 'application/json').
end((err, res) => {
err ? reject(err) : resolve(res.body)
})
));
}
else if (isFunction(url)) {
promise = url();
}
else {
promise = url;
}
return Promise.resolve(promise);
}
}
module.exports = {Await};
const React = require('react');
/**
* WaitOn
*/
class WaitOn extends React.Component {
static propTypes = {
handler: React.PropTypes.component.isRequired,
waitOn: React.React.PropTypes.string.isRequired
}
render() {
let {handler, waitOn, ...handlerProps} = this.props;
return (
Boolean(handlerProps[waitOn]) ?
<handler {...handlerProps}/>
: <div className="waiton-loading">Loading …</div>);
}
}
module.exports = {WaitOn}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment