Skip to content

Instantly share code, notes, and snippets.

@edfialk
Last active February 8, 2017 02:22
Show Gist options
  • Save edfialk/c7f12c64fa7b42f6b8c244850b1da2fc to your computer and use it in GitHub Desktop.
Save edfialk/c7f12c64fa7b42f6b8c244850b1da2fc to your computer and use it in GitHub Desktop.
React/Redux sample
/**
* /src/components/SolarTime/actions.js
* in a Redux app, api only allowed 1 day at a time, this is how I handled multiple days
*/
import * as c from './constants';
export const fetchDay = ( lat, lng, date ) => {
return function(dispatch){
return $.get(c.SUNTIME_URL + 'lat='+lat+'&lng='+lng+'&date='+date.format('YYYY-MM-DD'))
}
};
export const fetch = ({ address, dateStart, dateEnd }) => {
return function(dispatch){
if (dateEnd.diff(dateStart, "days") > 14){
dispatch(error('You cannot query more than 14 days at a time.'));
return;
}
dispatch(requestStart());
// address must be geocoded before subsequent requests
dispatch(fetchGeocode(address)).done(function(response){
if (response.status != "OK" || response.results.length == 0) {
dispatch(error('Invalid address query.'));
return;
}
const loc = response.results[0].geometry.location
const range = dateEnd.diff(dateStart, 'days');
let queries = [];
let date = moment(dateStart);
queries.push(dispatch(fetchDay(loc.lat, loc.lng, date)));
for(let i = 1; i < range; i++){
queries.push(dispatch(fetchDay(loc.lat, loc.lng, date.add(1, 'days'))));
}
$.when.apply($, queries).then(function(){
let suntimes = [];
for (let i = 0; i < arguments.length; i++){
if (arguments[i][0].status == 'OK'){
let r = arguments[i][0].results;
r.date = moment(r.sunrise).format('MM/DD/YYYY');
suntimes.push(r);
}
}
dispatch(requestEnd(suntimes));
});
}).fail(function(xhr, text, error){
dispatch(error(text));
});
}
}
/**
* /src/components/SolarTime/component.jsx
*/
import { setAddress, setDateStart, setDateEnd, fetchAll } from './actions';
class SolarTime extends Component {
componentDidMount() {
const { dispatch, address, dateStart, dateEnd } = this.props;
if (address && dateStart && dateEnd){
this.props.dispatch(fetchAll({ address, dateStart, dateEnd }));
}
}
/* other missing functions */
render() {
const { address, dateStart, dateEnd, error, suntimes, timeZone, isFetching } = this.props;
let table = '';
if (suntimes.length > 0){
table = <Table items={ this.generateItems() }/>
}
let loading = '';
if (isFetching){
loading = <div className="progress">
<div className="progress-bar progress-bar-striped active"></div>
</div>
}
return (
<div>
<Address address={address} onSubmit={ this.handleAddress }/>
<div className="row">
<div className="col-xs-6 text-right">
<h4>Start Date</h4>
<Calendar date={dateStart} handleChange={ this.handleDateStart }/>
</div>
<div className="col-xs-6">
<h4>End Date</h4>
<Calendar
date={dateEnd}
handleChange={ this.handleDateEnd }
minDate={dateStart}
maxDate={moment(dateStart).add(14, "days")}
/>
</div>
</div>
{ error && <div className="alert alert-danger">{error}</div> }
{ loading }
{ table }
</div>
);
}
}
/**
* /src/components/SolarTime/index.js
* This is the public API for this component
* Component can be included on /src/app/pages/IndexPage with import SolarTIme from '../components/SolarTime'
* constants, actions, etc. can also be imported
* this keeps actions, reducers, constants, etc. specific to this component inside this component's folder,
* rather than bogging down the main app actions file
*/
import * as actions from './actions';
import component from './component';
import * as constants from './constants';
import reducer from './reducer';
export default component;
export { actions, constants, reducer };
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment