Skip to content

Commit

Permalink
added optional before prop for rendering forms etc
Browse files Browse the repository at this point in the history
  • Loading branch information
capaj committed Jan 21, 2016
1 parent 4247db5 commit 1b71ffb
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 22 deletions.
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,23 @@ const ExampleWithAsync = (props) => <Async promise={prom} then={(val) => <div>{v
Much simpler, especially if your component is read-only, like the example.
In case you need user input before you can make the async call, there is a `before` property. Assign a function into it if you need to render a form for example.
```javascript
<Async before={(handlePromise) => {
return <form>
<input></input>
<button onClick={() => {
handlePromise(Promise.resolve('awesome data'))
}}>do something async like a POST request</button>
</form>
}}
/>
```
The form is rendered before the promise is resolved. If you ever need to reset the Async to `before` after promise has resolved/rejected get the Async ref and use
```javascript
ref.setState({started: false})
```
## install
With jspm:
Expand Down
46 changes: 29 additions & 17 deletions async.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
"format es6"
'format es6'
import React, {PropTypes} from 'react'

class Async extends React.Component {
constructor (props) {
super(props)
this.state = {}
this.state = {
started: false
}
}
componentWillReceiveProps (nP) {
if (nP.promise !== this.props.promise) {
Expand All @@ -14,6 +16,9 @@ class Async extends React.Component {
}
}
handlePromise (prom) {
this.setState({
started: true
})
prom.then((res) => {
this.setState({
resolved: res,
Expand All @@ -27,30 +32,37 @@ class Async extends React.Component {
})
}
componentWillMount () {
this.handlePromise(this.props.promise)
if (this.props.promise) {
this.handlePromise(this.props.promise)
}
}
render () {
const {props, state} = this
if (!state.finished) {
if (props.pendingRender) {
return props.pendingRender // custom component to indicate load in progress
if (state.started) {
if (!state.finished) {
if (props.pendingRender) {
return props.pendingRender // custom component to indicate load in progress
}
return <div></div>
}
return <div></div>
}
if (props.then && state.resolved) {
return props.then(state.resolved)
}
if (props.catch && state.rejected) {
return props.catch(state.rejected)
if (props.then && state.resolved) {
return props.then(state.resolved)
}
if (props.catch && state.rejected) {
return props.catch(state.rejected)
}
} else {
return this.props.before(this.handlePromise.bind(this))
}
}
}

Async.propTypes = {
then: PropTypes.func,
catch: PropTypes.func,
pendingRender: PropTypes.node,
promise: PropTypes.object.isRequired
before: PropTypes.func, // renders it's return value before promise is handled
then: PropTypes.func, // renders it's return value when promise is resolved
catch: PropTypes.func, // renders it's return value when promise is rejected
pendingRender: PropTypes.node, // renders it's value when promise is pending
promise: PropTypes.object // promise itself
}

export default Async
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-promise",
"version": "1.0.3",
"version": "1.1.0",
"description": "react.js component for rendering values behind promises",
"main": "async.js",
"scripts": {
Expand Down Expand Up @@ -28,7 +28,7 @@
"babel-preset-react": "^6.3.13",
"babel-register": "^6.3.13",
"chai": "^3.4.1",
"enzyme": "^1.2.0",
"enzyme": "^1.3.1",
"husky": "^0.10.2",
"mocha": "^2.3.4",
"react": "^0.14.3",
Expand Down
6 changes: 3 additions & 3 deletions test/async.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
'use strict'
import React from 'react'
import Async from '../async'
import { shallow, describeWithDOM, mount } from 'enzyme'
import { describeWithDOM, mount } from 'enzyme'
import {expect} from 'chai'

describeWithDOM('async', function () {
Expand All @@ -13,12 +13,12 @@ describeWithDOM('async', function () {
})

it('should render empty div when promise is pending', function () {
const wrapper = shallow(<Async promise={prom}/>)
const wrapper = mount(<Async promise={prom}/>)
expect(wrapper.html()).to.equal('<div></div>')
})

it('should render a supplied pendingRender prop when promise is pending', function () {
const wrapper = shallow(<Async promise={prom} pendingRender={<span>Loading ...</span>}/>)
const wrapper = mount(<Async promise={prom} pendingRender={<span>Loading ...</span>}/>)
expect(wrapper.html()).to.equal('<span>Loading ...</span>')
})

Expand Down

0 comments on commit 1b71ffb

Please sign in to comment.