UNPKG

@eggtronic/react-weather-widget

Version:
70 lines (63 loc) 2.26 kB
import useAsync from './useAsync'; import useGeoLocation from './useGeoLocation'; import { OpenWeatherMapExclude, WeatherData } from '../types/weatherWidget'; import { BASE_API_URL } from '../utils/index'; /** * * @param key api key from openweathermap * @param units * For temperature in Fahrenheit, use units=imperial * For temperature in Celsius, use units=metric * Kelvin is used by default, so there is no need to use the units parameter in the API call if you want this * @param exclude https://openweathermap.org/api/one-call-api */ export default function useFetchWeather( key: string, units?: string, exclude?: OpenWeatherMapExclude, geo?: { lat: string, lon: string } | undefined ) { const { latitude, longitude, loading, error, shouldDetectLocation } = useGeoLocation(!!geo); const state = useAsync(async () => { if (loading) return { loading: true }; if (error) return { error, loading: false }; const url = `${BASE_API_URL}` + `lat=${geo?.lat || latitude}` + `&lon=${geo?.lon || longitude}` + `${units ? `&units=${units}` : ''}` + `${exclude ? `&exclude=${exclude.join(',')}` : ''}` + `&appid=${key}`; const response = await fetch(url); const result = await response.json(); return result; }, [latitude, longitude, loading, error]); const errorMsg: string | undefined = state.value?.error?.message || state.error?.message; /** there is a hack to check if it is currently loading geo or weather data * if loading is true then geo is loading. * if geo loaded, and if there is no error and no timezone * then weather is loading. */ let loadingMsg: string | null = null; if (shouldDetectLocation) { if (loading) { loadingMsg = 'Geo Locating ...'; } else if (!state.value.timezone && !errorMsg) { loadingMsg = 'Fetching Weather Data ...'; } } if (!shouldDetectLocation) { if (state.loading && !errorMsg) { loadingMsg = 'Fetching Weather Data ...'; } } const weatherData: WeatherData | null = state.value ? state.value : null; return [errorMsg, loadingMsg, weatherData]; }