Last active
July 7, 2020 00:19
-
-
Save dhawkinson/3ed71c4319d12fc03003d5100c614fa8 to your computer and use it in GitHub Desktop.
Gist for soliciting help on a project
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
***** My Component ***** | |
// client/src/components/pages/functional/Weather.js | |
import React, { useEffect } from 'react'; | |
import { connect, useDispatch } from 'react-redux'; | |
import PropTypes from 'prop-types'; | |
import Moment from 'react-moment'; | |
import Spinner from '../../helpers/Spinner' | |
import { getWeather } from '../../../redux/actions/weather' | |
const Weather = ({ getWeather, forecast, loading }) => { | |
const dispatch = useDispatch(); | |
// upon load - execute useEffect() only once -- loads forecast into state | |
useEffect(() => { dispatch(getWeather()); }, [dispatch, getWeather]) | |
return ( | |
<div id='page-container'> | |
<div id='content-wrap' className='Weather'> | |
{ loading ? | |
<Spinner /> : | |
<> | |
<div className='WeatherHead box mt-3'> | |
<h4 className='report-head'>Weather Report</h4> | |
</div> | |
{/* Current Weather Conditions */} | |
<h6 className='current-head'>Current Conditions</h6> | |
<section className='CurrentlyGrid box mt-3'> | |
<span>Now</span> | |
<span>Summary</span> | |
<span>Icon</span> | |
<span>Precip</span> | |
<span>Temp</span> | |
<span>Humid</span> | |
<span>Visblty</span> | |
<span>Wind Spd</span> | |
<span><Moment parse='HH:mm'>`${forecast.currently.time}`</Moment></span> | |
<span>`${forecast.currently.summary}`</span> | |
<span>`${forecast.currently.icon}`</span> | |
<span>`${forecast.currently.precipProbability}`</span> | |
<span>`${forecast.currently.temperature}`</span> | |
<span>`${forecast.currently.humidity}`</span> | |
<span>`${forecast.currently.visibility}`</span> | |
<span>`${forecast.currently.windSpeed}`</span> | |
</section> | |
{/* Eight Day Forecast */} | |
/* ... code deleted for brevity ...*/ | |
</> | |
} | |
</div> | |
</div> | |
); | |
}; | |
Weather.propTypes = { | |
getWeather: PropTypes.func.isRequired, | |
forecast: PropTypes.object.isRequired | |
}; | |
const mapStateToProps = state => { | |
return { forecast: state.weather.forecast } | |
}; | |
export default connect( mapStateToProps, { getWeather } )(Weather); | |
***** My Action Creator ***** | |
// client/src/redux/actions/weather.js | |
// node modules | |
import axios from 'axios'; | |
import chalk from 'chalk'; | |
// local modules | |
import { | |
GET_FORECAST, | |
FORECAST_ERROR | |
} from './types'; | |
export const getWeather = () => async dispatch => { | |
console.log(chalk.blue('ACTION CREATOR got here ')); | |
try { | |
// get weather forecast | |
const res = await axios.get(`/api/weather`); | |
console.log(chalk.yellow('ACTION CREATOR getWeather ', res)); | |
// pass only the currently & daily segments of the api | |
const forecast = { | |
currently: res.data.currently, | |
daily: res.data.daily.data | |
} | |
// SUCCESS - set the action -- type = GET_WEATHER & payload = res.data (the forecast) | |
dispatch({ | |
type: GET_FORECAST, | |
payload: forecast | |
}); | |
} catch (err) { | |
// FAIL - set the action FORECAST_ERROR, no payload to pass | |
console.log('FORECAST_ERROR ',err) | |
dispatch({ | |
type: FORECAST_ERROR | |
}); | |
}; | |
}; | |
***** My Reducer ***** | |
//client/src/redux/reducers/weather.js | |
import { | |
GET_FORECAST, | |
FORECAST_ERROR, | |
} from '../actions/types' | |
const initialState = { | |
forecast: null, | |
loading: true | |
} | |
export default (state = initialState, action) => { | |
const { type, payload } = action | |
switch (type) { | |
case GET_FORECAST: | |
return { | |
...state, | |
forecast: payload, | |
loading: false | |
} | |
case FORECAST_ERROR: | |
return { | |
...state, | |
forecast: null, | |
loading: false | |
} | |
default: | |
return state | |
} | |
} | |
***** My Server-side Route ***** | |
//server/routes/api/weather.js | |
// node modules | |
const express = require('express'); | |
const axios = require('axios'); | |
const chalk = require('chalk'); | |
const router = express.Router(); | |
router.get('/weather', async (req, res) => { | |
try { | |
// build url to weather api | |
const keys = require('../../../client/src/config/keys'); | |
const baseUrl = keys.darkskyBaseUrl; | |
const apiKey = keys.darkskyApiKey; | |
const lat = keys.locationLat; | |
const lng = keys.locationLng; | |
const url = `${baseUrl}${apiKey}/${lat},${lng}`; | |
console.log(chalk.blue('SERVER SIDE ROUTE FORECAST URL ', url)); | |
const res = await axios.get(url); | |
// forecast -- strip down res, only using currently{} & daily{} | |
const weather = { | |
currently: res.data.currently, | |
daily: res.data.daily.data | |
}; | |
console.log(chalk.yellow('SERVER SIDE ROUTE FORECAST DATA ', weather)); | |
// return weather | |
res.json({ weather }); | |
} catch (error) { | |
console.error(chalk.red('ERR ',error.message)); | |
res.status(500).send('Server Error'); | |
} | |
}); | |
module.exports = router; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment