Skip to content

Instantly share code, notes, and snippets.

@pi3r0
Created September 4, 2019 12:13
Show Gist options
  • Save pi3r0/b299379c836665fcb00e5dd032d42ee0 to your computer and use it in GitHub Desktop.
Save pi3r0/b299379c836665fcb00e5dd032d42ee0 to your computer and use it in GitHub Desktop.
Refactoring work - this a react component, working independently, this show weather forecast, at the refresh from the user location if user allowed this and via a search bar (inside the component) where you write a city name, then it fetches the result.
// Don't bother with import classes, this is not the problem here, you can add one if you have to.
// The goal is to refactor the functions (getWeather / getLocation) and inside the render() function.
// You can change state var or add one. things must be write once if it's possible and your code must be clear
// and understandable.
import React from "react";
import Form from "./Form";
import WeatherDiv from "./WeatherDiv";
import "./Form.css"
import "./WeatherAPi.css"
import Slider from "react-slick"
import ActivityCards from "./ActivityCards"
import Activity from "./Activity.json"
import { Link } from 'react-router-dom'
class WeatherAPI extends React.Component {
state = {
city: '',
//just a UI state to show or hide loading div, and i think that the bug comes from here
loading: true,
erreur:'',
weatherData: []
}
//Called when the user write city into the searching bar
getWeather = (e) => {
// In any case prevent default (safety) if will stop another request already launched
e.preventDefault();
const city = e.target.city.value;
this.retrieveWeather("q=" + city)
}
//fonction qui permet d'obtenir la localisation
getLocation = () => {
//si l'utilisateur accepte d'être géolocalisé
if (navigator.geolocation) {
//getCurrentPosition permet de retourner un objet position qui donne notamment les coordonnées
navigator.geolocation.getCurrentPosition(position => {
// Get the weather with user lat and long
this.retrieveWeather("lat="+ position.coords.latitude + "&lon=" + position.coords.longitude)
})
} else {
//alerte qui s'active si l'utilisateur n'accepte pas d'être géolocalisé
}
}
retrieveWeather = (fetchParams) => {
//Set loading to true, so the UI with display loading screen, set to false after the result
this.setState({ loading : true }
//Your service is the same call with each exept for the params (q=${city} or lat=${this.state.lat}&lon=${this.state.lon})
fetch(`http://api.openweathermap.org/data/2.5/forecast?`+ ${fetchParams} + `&lang=fr&units=metric&appid=e8fc88dd5f1edd7f7ff6a9a5be06bd83`)
.then(res => res.json())
.then(res => this.setState({
weatherData: res,
city: res.city.name,
loading: false,
erreur:'pfffff'}))
}
}
//This method is called once at the page creation, you have not to worry to test if it's geoloc or city search
componentDidMount() {
//for the first time, check user location and then retrieve the weather
this.getLocation()
}
render() {
const param = {
dots: true,
infinite: true,
speed: 1500,
slidesToShow: 3,
slidesToScroll: 3,
initialSlide: 0,
responsive: [
{
breakpoint: 1024,
settings: {
slidesToShow: 3,
slidesToScroll: 3,
infinite: true,
dots: false,
}
},
{
breakpoint: 600,
settings: {
slidesToShow: 2,
slidesToScroll: 2,
initialSlide: 0,
infinite: true
}
},
{
breakpoint: 480,
settings: {
slidesToShow: 2,
slidesToScroll: 2,
infinite: true,
repeat: 99
}
}
]
}
const settings = {
dots: false,
infinite: false,
speed: 800,
slidesToShow: 1,
slidesToScroll: 1
};
//le if/else, permet de s'assurer que le render ne s'active que quand l'API a bien chargé ses données dans le state et donc transformé loading en false
if (this.state.loading) {
return (<div>loading</div>)
} else if (this.state.weatherData.list[0].weather[0].main === "Rain") {
return (
<div>
<div>
<Form getWeather={this.getWeather} city={this.state.city} />
</div>
<div>
<Slider {...settings} >
{/*le filter map permet de ne sélectionner que une prévision par jour dans le tableau d'objets list contenu dans l'objet weatherData. Autrement list contient des prévisions toutes les trois heures. */}
{this.state.weatherData.list
.filter(data => data.dt_txt.includes("12:00:00"))
.map((data, index) => (
<WeatherDiv {...data} city={this.state.city} index={index} key={index} />
))}
</Slider>
</div>
<Slider className="sliderActivity"{...param}>
{Activity.filter(data => data.type.toString().includes("beau"))
.map((data) => {
let url = `/activity/${data.id}`
return (
<div key={data.id}>
<Link to={url}> <ActivityCards {...data} /></Link>
</div>
)
})}
</Slider>
</div>
)
} else {
return (
<div>
<div>
<Form getWeather={this.getWeather} city={this.state.city} />
</div>
<div>
<Slider {...settings} >
{/*le filter map permet de ne sélectionner que une prévision par jour dans le tableau d'objets list contenu dans l'objet weatherData. Autrement list contient des prévisions toutes les trois heures. */}
{this.state.weatherData.list
.filter(data => data.dt_txt.includes("12:00:00"))
.map((data, index) => (
<WeatherDiv {...data} city={this.state.city} erreur={this.state.erreur} index={index} key={index} />
))}
</Slider>
</div>
<Slider className="sliderActivity"{...param}>
{Activity.map((data) => {
let url = `/activity/${data.id}`
return (
<div key={data.id}>
<Link to={url}>
<ActivityCards {...data} />
</Link>
</div>
)
})}
</Slider>
</div>
)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment