javascriptreactjsweatherdarksky

Variable wont update on API link ReactJS


I have a problem with updating a variable on my API link. So this should work that at the start coords on this API link should be 0,0 (or at the best case it should at first display geonavigator window and after accepting it it should display weather for your coords then after searching for another city at the same place should appear weather for searched city but still don't know how to do it) and this part works but after I search for another city on the search bar the coords on API link (coordinates.lat and coordinates.lng) should change to the coords of searched city and the changed weather should be displayed on the screen but this part doesn't work. Maybe works a bit because it look like the value on coordinates.lat and coordinates.lng are changing everytime I search for any city when I display them after return on <p>Latitude: {coordinates.lat}</p> <p>Longtitude: {coordinates.lng}</p> but weather isn't changing at all, its still displayed for 0,0 coords. I'm sorry for mess in my code but I'm still learning. And also I'm talking about that first API link which is

const api = `${proxy}https://api.darksky.net/forecast/1539bbb708779eef3993021296196cb2/${coordinates.lat},${coordinates.lng}`; 
import React, { useEffect, useState, } from "react";
import "./PogodaL.css";
import "./PogodaS.css";
import "./PogodaP.css";
import Skycons from "react-skycons"; 
import "./App.css";
import lupa from "./lupa.png";
import PlacesAutocomplete,{
  geocodeByAddress,
  getLatLng
} from "react-places-autocomplete";



export function App2() {
  const [state, setState] = useState({
    long: null,
    lat: null,
    precipProbability: "",
    temperatureDegree: 0,
    locationTimezone: "",
    minimalna: 0,
    maksymalna: 0,
    icons: ""
  });
  const [state2, setState2] = useState({
    long: null,
    lat: null,
    precipProbability: "",
    temperatureDegree: 0,
    locationTimezone: "",
    minimalna: 0,
    maksymalna: 0,
    icons: ""
  });

  const [state3, setState3] = useState({
    long: null,
    lat: null,
    precipProbability: "",
    temperatureDegree: 0,
    locationTimezone: "",
    minimalna: 0,
    maksymalna: 0,
    icons: ""
  });

  const [state4, setState4] = useState({
    long: null,
    lat: null,
    precipProbability: "",
    temperatureDegree: 0,
    locationTimezone: "",
    minimalna: 0,
    maksymalna: 0,
    icons: ""
  });

  const [address, setAddress] = useState(""); /* here is the start of defining variables */
  const [coordinates, setCoordinates] = useState({ 
      lat: 0, 
      lng: 0});

  const handleSelect = async (value) => {
      const results = await geocodeByAddress(value);
      const latLng = await getLatLng(results[0]);
      setAddress(value);
      setCoordinates(latLng);
  }
  

  useEffect(() => {
    if (navigator.geolocation) {
      navigator.geolocation.getCurrentPosition(position => {
        const lat = position.coords.latitude;
        const long = position.coords.longitude;
        setState({
          ...state,
          lat,
          long
        });

        const proxy = "https://cors-anywhere.herokuapp.com/";
        const api = `${proxy}https://api.darksky.net/forecast/1539bbb708779eef3993021296196cb2/${coordinates.lat},${coordinates.lng}`;  /* here is that API Link*/
        
        fetch(api)
          .then(response => {
            return response.json();
          })
          .then(data => {
            console.log(data);
            const { temperature, precipProbability, icon } = data.currently;
            
            const celcjusz = ((temperature - 32) * 5) / 9;

            const { temperatureLow } = data.daily.data[1];
            const celcjusz1 = ((temperatureLow - 32) * 5) / 9;

            const { temperatureMax } = data.daily.data[1];
            const celcjusz2 = ((temperatureMax - 32) * 5) / 9;
            
            setState({
              ...state,
              
              temperatureDegree: Math.floor(celcjusz),
              locationTimezone: data.timezone,
              minimalna: Math.floor(celcjusz1),
              maksymalna: Math.floor(celcjusz2),
              precipProbability: precipProbability.toString().replace(/0.0/g, '').replace(/0./g,''), 
              icons: icon.replace(/-/g, "_").toUpperCase() 
            });
            
          });
          const apiL = `${proxy}https://api.darksky.net/forecast/1539bbb708779eef3993021296196cb2/50,23` ;
          fetch(apiL)
          .then(response => {
            return response.json();
          })
          .then(data => {
            console.log(data);
            const { temperature, precipProbability, icon } = data.currently;

            const celcjusz = ((temperature - 32) * 5) / 9;

            const { temperatureLow } = data.daily.data[1];
            const celcjusz1 = ((temperatureLow - 32) * 5) / 9;

            const { temperatureMax } = data.daily.data[1];
            const celcjusz2 = ((temperatureMax - 32) * 5) / 9;
            
            setState2({
              ...state2,
              precipProbability: precipProbability.toString().replace(/0.0/g, '').replace(/0./g,''), 
              temperatureDegree: Math.floor(celcjusz),
              locationTimezone: data.timezone,
              minimalna: Math.floor(celcjusz1),
              maksymalna: Math.floor(celcjusz2),
              icons: icon.replace(/-/g, "_").toUpperCase()            
            });         
          });

          const apiS = `${proxy}https://api.darksky.net/forecast/1539bbb708779eef3993021296196cb2/52.50,13.28` ;
          fetch(apiS)
          .then(response => {
            return response.json();
          })
          .then(data => {
            console.log(data);
            const { temperature, precipProbability, icon } = data.currently;

            const celcjusz = ((temperature - 32) * 5) / 9;

            const { temperatureLow } = data.daily.data[1];
            const celcjusz1 = ((temperatureLow - 32) * 5) / 9;

            const { temperatureMax } = data.daily.data[1];
            const celcjusz2 = ((temperatureMax - 32) * 5) / 9;
            
            setState3({
              ...state3,
              precipProbability: precipProbability.toString().replace(/0.0/g, '').replace(/0./g,''), 
              temperatureDegree: Math.floor(celcjusz),
              locationTimezone: data.timezone,
              minimalna: Math.floor(celcjusz1),
              maksymalna: Math.floor(celcjusz2),
              icons: icon.replace(/-/g, "_").toUpperCase()            
            });         
          });
          const apiP = `${proxy}https://api.darksky.net/forecast/1539bbb708779eef3993021296196cb2/40.69,-74.11`;
          fetch(apiP)
          .then(response => {
            return response.json();
          })
          .then(data => {
            console.log(data);
            const { temperature, precipProbability, icon } = data.currently;

            const celcjusz = ((temperature - 32) * 5) / 9;

            const { temperatureLow } = data.daily.data[1];
            const celcjusz1 = ((temperatureLow - 32) * 5) / 9;

            const { temperatureMax } = data.daily.data[1];
            const celcjusz2 = ((temperatureMax - 32) * 5) / 9;
            
            setState4({
              ...state4,
              precipProbability: precipProbability.toString().replace(/0.0/g, '').replace(/0./g,''), 
              temperatureDegree: Math.floor(celcjusz),
              locationTimezone: data.timezone,
              minimalna: Math.floor(celcjusz1),
              maksymalna: Math.floor(celcjusz2),
              icons: icon.replace(/-/g, "_").toUpperCase()            
            });         
          });

      });
    }
  }, []);
  return (
 
    <div className="App">
      <div>
        <PlacesAutocomplete 
        
        value={address} 
        onChange={setAddress} 
        onSelect={handleSelect}
        >{({getInputProps, suggestions, getSuggestionItemProps, loading}) => (
        <div class="Search-Bar">
            <p>Latitude: {coordinates.lat}</p> {/* I display it there and it changed everytime I search for any city so this works there */} 
            <p>Longtitude: {coordinates.lng}</p>
            
            <input {...getInputProps({placeholder: "Wpisz lokalizację"})} />
            <button type="submit"><img src={lupa} /></button>
            

            {suggestions.map((suggestion) => {
                const style = {
                    backgroundColor: suggestion.active ? "#41b6e6" : "#e6eeff"
                }
               return ( <div {...getSuggestionItemProps(suggestion, { style })} class="Suggestion"> {suggestion.description} </div> 
               )
               }  
             )
            }
              
        </div> 
        )
        }
  

        </PlacesAutocomplete>
    </div>
     
      <div class="location">
  <h1 class="location-timezone"> {state.locationTimezone} </h1> </div>
       <div class="icon"> <Demo icons={state.icons} /> </div>
      
      <div class="temperature">
        <div class="degree-section">
          <span> {state.temperatureDegree}°C </span>
        </div>
        <div class="precipProbability">
          {"Szansa opadów: "}
          {state.precipProbability}{"% "}
        </div>
      </div>

      <div class="sekcja-jutro">
        <h1>Pogoda na Jutro: </h1>
      </div>

      <div class="minimalna">
        <span> Temperatura minimalna:</span>
        <h1 class="temperatura-minimalna"> {state.minimalna} </h1>
        <span> °C </span>
      </div>

      <div class="maksymalna">
        <span>Temperatura maksymalna:</span>
        <h1 class="temperatura-maksymalna"> {state.maksymalna}</h1>
        <span>°C</span>
      </div>

 
      <div class="locationL">
  <h1 class="location-timezoneL"> {state2.locationTimezone} </h1> </div>
        
      

      <div class="temperatureL">
        <div class="degree-sectionL">
        <div class="iconL"><Demo icons={state2.icons} />  </div>  
          <span> {state2.temperatureDegree}°C </span>
        </div>
        <div class="temperature-descriptionL">
          {"Szansa opadów: "}
          {state2.precipProbability}{"%"}
        </div>
      </div>  

      <div class="locationS">
  <h1 class="location-timezoneS"> {state3.locationTimezone} </h1> </div>      
      <div class="temperatureS">
        <div class="degree-sectionS">
        <div class="iconS"><Demo icons={state3.icons} />  </div>  
          <span> {state3.temperatureDegree}°C </span>
        </div>
        <div class="temperature-descriptionS">
          {"Szansa opadów: "}
          {state3.precipProbability}{"%"}
        </div>
      </div>  

      <div class="locationP">
  <h1 class="location-timezoneP"> {state4.locationTimezone} </h1> </div>      
      <div class="temperatureP">
        <div class="degree-sectionP">
        <div class="iconP"><Demo icons={state4.icons} />  </div>  
          <span> {state4.temperatureDegree}°C </span>
        </div>
        <div class="temperature-descriptionP">
          {"Szansa opadów: "}
          {state4.precipProbability}{"%"}
        </div>
      </div> 
      
    </div>
    
    

    

  );
}

class Demo extends React.Component {
  render() {
    return (
      <Skycons
        
        color="white"
        icon={this.props.icons} 
        autoplay={true}
        height="130"
      />
    );
  }
}
export default App2;

Solution

  • This will get called only once when it loads/mounts component

    useEffect(() => {
         ...
    },[]);
    

    You can pass the coordinates as dependency, so useEffect will get called whenever there is change in coordinates

    useEffect(() => {
         ...
    },[coordinates]); // <----- HERE