fetchData.js -> File where we fetch the data. This file is later imported and the functions will be used to display the fetched data.
import { weatherAPIConfig } from "../weatherAPIConfig"
export async function fetchWeatherForecast(cityName) {
let URL = `https://api.openweathermap.org/data/2.5/weather?q=${cityName}&units=metric&appid=${weatherAPIConfig.key}`
try {
const fetchWeatherForecast = await fetch(URL)
const weatherForecastJSON = await fetchWeatherForecast.json()
return weatherForecastJSON
}
catch (error) {
console.log("Could not find given city");
return "Could not find given city"
}
}
export function getWeatherDescription(weatherForecastJSON) {
return weatherForecastJSON.weather[0].description;
}
export function getWeatherTemperature(weatherForecastJSON) {
return weatherForecastJSON.main.temp
}
export function getWeatherWindSpeed(weatherForecastJSON) {
return weatherForecastJSON.wind.speed;
}
export function getWeatherHumidity(weatherForecastJSON) {
return weatherForecastJSON.main.humidity
}
Row.js -> The file where the temperature etc. is displayed in div
import React from 'react'
import {getWeatherDescription, getWeatherHumidity, getWeatherTemperature, getWeatherWindSpeed, fetchWeatherForecast} from '../../functions/fetchData'
import { weatherAPIConfig } from '../../weatherAPIConfig';
function Row() {
return (
<div>
<div>API-key: {weatherAPIConfig.key}</div>
<div>Result: {getWeatherDescription(fetchWeatherForecast("London"))}</div>
</div>
)
}
export default Row;
........................................................................................
I recommend having your "fetchWeatherForecast" function return an object with those methods available for parsing:
import { weatherAPIConfig } from "../weatherAPIConfig"
export async function fetchWeatherForecast(cityName) {
let URL = `https://api.openweathermap.org/data/2.5/weather?q=${cityName}&units=metric&appid=${weatherAPIConfig.key}`
try {
const weatherForecast = await fetch(URL) //changed cuz I don't recommend naming your variable the same as the function
const weatherForecastJSON = await fetchWeatherForecast.json()
} catch (error) {
console.log("Could not find given city");
return "Could not find given city"
}
function getWeatherDescription() {
return weatherForecastJSON.weather[0].description;
}
function getWeatherTemperature() {
return weatherForecastJSON.main.temp
}
function getWeatherWindSpeed() {
return weatherForecastJSON.wind.speed;
}
function getWeatherHumidity() {
return weatherForecastJSON.main.humidity
}
return {getWeatherDescription, getWeatherTemperature, getWeatherWindSpeed, getWeatherHumidity}
}
So now in your "Row.js", you can do:
import React from 'react'
import {fetchWeatherForecast} from '../../functions/fetchData'
import { weatherAPIConfig } from '../../weatherAPIConfig';
const {useEffect, useState} = React;
function Row() {
var [forecast, setForecast] = useState({});
useEffect(()=>{
fetchWeatherForecast("London").then((forecastObj)=>setForecast(forecastObj));
}, [])
return (
<div>
<div>API-key: {weatherAPIConfig.key}</div>
<div>Result: {forecast.getWeatherDescription?.()}</div>
</div>
)
}
export default Row;
As a disclaimer, I haven't tested this code. But the gist of it is, have the "fetchweatherForecast" method return an object with methods that can access the "weatherForecastJSON" object. Then instantiate this object within your "Row.js" and render the data with the methods returned from the "weatherForecastJSON" object.
Edit: As noted by @Patrick Roberts, "forecast.getWeatherDescription()" would throw an error the first render. To remedy that, I've used optional chaining which would call the function only if it exists on the object. The alternative would be:
<div>Result: {forecast.getWeatherDescription ? forecast.getWeatherDescription() : ''}</div>