I’m encountering an issue with my React application where I’m unable to update the weather details based on the selected city using the OpenWeatherMap API. Here’s the setup:
-
I have a parent component
App
which manages the state of latitude and longitude. -
Inside
App
, I have a child componentDisplayFetch
that fetches weather details based on latitude and longitude. -
I also have another child component
SearchCities
insideDisplayFetch
, which allows users to search for a city and updates the latitude and longitude when a city is selected.
The problem arises when I select a new city in SearchCities
. Although the latitude and longitude are updated correctly in the App
component, the weather details displayed in DisplayFetch
do not update accordingly. The weather details remain associated with the previous location, rather than updating to the weather of the newly selected city.
I’ve ensured that the updateLocation
function in the App
component correctly updates the state of latitude and longitude, and it is being passed down to DisplayFetch
and further to SearchCities
. Additionally, I’ve confirmed that the update
function (passed from DisplayFetch
to SearchCities
) is being called when a new city is selected, and it is correctly updating the latitude and longitude.
import React, { useState, useEffect } from "react";
import DisplayFetch from "./components/DisplayFetch";
export default function App() {
const [latitude, setLatitude] = useState(null);
const [longitude, setLongitude] = useState(null);
useEffect(() => {
navigator.geolocation.getCurrentPosition(
(position) => {
console.log(position.coords.latitude);
console.log(position.coords.longitude);
setLatitude(position.coords.latitude);
setLongitude(position.coords.longitude);
},
(error) => {
console.error("Error getting current geolocation:", error);
}
);
}, []);
const updateLocation = (lat, long) => {
setLatitude(lat);
setLongitude(long);
};
return (
<div className="flex items-center justify-center h-screen bg-darkSlate">
<div>
{latitude} {longitude}
</div>
{latitude !== null && longitude !== null ? (
<DisplayFetch
latitude={latitude}
longitude={longitude}
updateLocation={updateLocation}
/>
) : (
<p>Loading...dasdasdasdasdas</p>
)}
</div>
);
}
import React, { useState, useEffect } from "react";
import WeatherBox from "./WeatherBox";
import { CiLocationOn } from "react-icons/ci";
import { AsyncPaginate } from "react-select-async-paginate";
import SearchCities from "./SearchCities";
const DisplayFetch = ({ latitude, longitude, updateLocation }) => {
const [data, setData] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
fetchData();
}, []);
const fetchData = async () => {
try {
const response = await fetch(
`https://api.openweathermap.org/data/2.5/weather?lat=${latitude}&lon=${longitude}&appid=MYAPI`
);
// Replace with your API endpoint
if (!response.ok) {
throw new Error("Network response was not ok.");
}
const data = await response.json();
setData(data);
setLoading(false);
} catch (error) {
setError(error.message);
setLoading(false);
}
};
return (
<>
{loading ? (
<p>Loading...</p>
) : error ? (
<p>Error: {error}</p>
) : (
<div className="bg-paleBlue p-8 rounded-lg shadow-lg flex flex-col">
<div className="relative border border-solid border-gray-300 rounded-md mb-4">
<div>
{latitude} {longitude}
</div>
<SearchCities
latCity={latitude}
longCity={longitude}
update={updateLocation} // Pass updateLocation here
/>
<div className="absolute inset-y-0 right-0 flex items-center pr-2"></div>
</div>
<div className="grid grid-cols-2 gap-4">
<WeatherBox title="Min Temp" value={`${data.main.temp_min}°C`} />
<WeatherBox title="Max Temp" value={`${data.main.temp_max}°C`} />
<WeatherBox
title="Feels Like"
value={`${data.main.feels_like}°C`}
/>
<WeatherBox title="Pressure" value={`${data.main.pressure} hPa`} />
<WeatherBox title="Humidity" value={`${data.main.humidity}%`} />
<WeatherBox title="Wind Speed" value={`${data.wind.speed} m/s`} />
</div>
</div>
)}
</>
);
};
export default DisplayFetch;
import React, { useState, useEffect } from "react";
import { AsyncPaginate } from "react-select-async-paginate";
import { geoApiOptions, GEO_API_URL } from "../components/api";
import DisplayFetch from "./DisplayFetch";
const SearchCities = ({ latCity, longCity, update }) => {
const [search, setSearch] = useState(null);
const loadOptions = (inputValue) => {
return fetch(
`${GEO_API_URL}/cities?minPopulation=1000&namePrefix=${inputValue}`,
geoApiOptions
)
.then((response) => response.json())
.then((response) => {
return {
options: response.data.map((city) => {
return {
value: `${city.latitude} ${city.longitude}`,
label: `${city.name}, ${city.countryCode}`,
};
}),
};
});
};
const handleOnChange = (searchData) => {
setSearch(searchData);
console.log(latCity);
console.log(longCity);
if (searchData) {
const [lat, long] = searchData.value.split(" ");
update(lat, long);
} else {
// Clear the latitude and longitude when no city is selected
update(null, null);
}
console.log(latCity);
console.log(longCity);
};
return (
<>
<AsyncPaginate
placeholder="Search for city"
debounceTimeout={600}
value={search}
onChange={handleOnChange}
loadOptions={loadOptions}
/>
<>
<div>
{latCity} from search city{longCity}
</div>
</>
</>
);
};
export default SearchCities;
please anybody find my eroors . i am strucked and tired….