skip to Main Content

I am working with OpenWeatherMap in order to grab the current weather of, say, Helsinki.

My latest MNWE (N as non) is:

import axios from 'axios'

const apiKey = import.meta.env.VITE_OWM_API_KEY

const getCityCoordinatesApiUrl = (city) => {
    return `https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${apiKey}`
}

const getCityWeatherApiUrl = (longitude, latitude) => {
    return `https://api.openweathermap.org/data/2.5/onecall?lat=${latitude}&lon=${longitude}&appid=${apiKey}`
}

const getCityWeather = (city, weatherJsonContainer) => {
    const url = getCityCoordinatesApiUrl(city)
    let longitude = null
    let latitude = null

    axios.get(url).then(response => {
        console.log("Hell", response.data)
        longitude = response.data.coord.lon
        latitude = response.data.coord.lat
    })
    .catch(error => {
        console.log("Error in getCityWeather:", error)
        alert(`Could not obtain weather of ${city}!`)
    })

    console.log("getCityWeather: received:", latitude, longitude)

    const url2 = getCityWeatherApiUrl(longitude, latitude)

    const outData = axios.get(url2).then(response => response.data)
    
    console.log("getCityWeather: outData:", outData)
}

My problem is that longitude and latitude stay as null. How can I resolve this issue? I have been working on it for several hours now.

Edit 1

After trying code kindly provided by urchmaney, my problematic implementation transforms into the following:

import axios from 'axios'

const apiKey = import.meta.env.VITE_OWM_API_KEY

const getCityCoordinatesApiUrl = (city) => {
    return `https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${apiKey}`
}

const getCityWeatherApiUrl = (longitude, latitude) => {
    return `https://api.openweathermap.org/data/2.5/onecall?lat=${latitude}&lon=${longitude}&appid=${apiKey}`
}

const getCityWeather = (city) => {
    const url = getCityCoordinatesApiUrl(city)

    axios.get(url).then(response => {
        const longitude = response.data.coord.lon
        const latitude = response.data.coord.lat
        const url2 = getCityWeatherApiUrl(longitude, latitude)
        return axios.get(url2);
    })
    .then(response => {
        console.log(response.data)
        return response.data
    })
    .catch(error => {
        console.log("Error in getCityWeather:", error)
        alert(`Could not obtain weather of ${city}!`)
    })
}

export default {
    getCityWeather
}

(Calling the above)

const weatherJsonData = weatherService.getCityWeather('Helsinki')

Now, my problem is in the 2nd then: return response.data returns undefined.

3

Answers


  1. you need to wait for 1st request to finish. Put the code after .catch() in a .then() statement

    Login or Signup to reply.
  2. You need to chain the API calls. The way you are trying to access the longitude and latitude is not in the right context. the assignment line console.log("getCityWeather: received:", latitude, longitude) is ran before the API call is returned.

    To chain the API call you will do like this

        axios.get(url).then(response => {
            console.log("Hell", response.data)
            longitude = response.data.coord.lon
            latitude = response.data.coord.lat
            console.log("getCityWeather: received:", latitude, longitude)
            const url2 = getCityWeatherApiUrl(longitude, latitude)
            return axios.get(url2)
        })
         .then(res => {
          console.log("getCityWeather: outData:", res.data)
        })
        .catch(error => {
            console.log("Error in getCityWeather:", error)
            alert(`Could not obtain weather of ${city}!`)
        })
    

    Async / Await Implementation

    
    const getCityWeather = async(city) => {
       try {
          const response = await axios.get(url)
          const longitude = response.data.coord.lon
          const latitude = response.data.coord.lat
          const url2 = getCityWeatherApiUrl(longitude, latitude)
          return axios.get(url2)
       }
       catch (error) {
          console.log("Error in getCityWeather:", error)
          alert(`Could not obtain weather of ${city}!`)
       }
    }
    
    

    Remember it is an async method so you need to await it when consuming it

    const weatherJsonData = await weatherService.getCityWeather('Helsinki')
    
    Login or Signup to reply.
  3. Send the city, lat, lon, appid as query params. I have altered the api call url based on this docs.

    Try using async-await for better promises handling.

    const url = "https://api.openweathermap.org/data/2.5/weather"
    
    const getCityWeather = async(city) => {
    try {
      const response = await axios.get(url, {
        params: {
          q: city,
          appid: apiKey,
        },
      });
      console.log(response);
      const longitude = response.data.coord.lon;
      const latitude = response.data.coord.lat;
      const response2 = await axios.get(url, {
        params: {
          lat: latitude,
          lon: longitude,
          appid: apiKey,
        },
      });
      console.log(response2);
      return response2.data;
    } catch (err) {
      alert(`Could not obtain weather of ${city}!`);
      console.log(err);
    }
    

    I have removed the two functions as the urls are same and sent the data using axios params.
    This will resolve the issue.

    Using .then() and .catch():

    Changes in your code:

    axios.get(url).then(response => {
        const longitude = response.data.coord.lon
        const latitude = response.data.coord.lat
        const url2 = getCityWeatherApiUrl(longitude, latitude)
    
        // response need to be caught by .then() as a callback. It should not be returned.
        axios.get(url2).then(response => {
             console.log(response.data)
             return response.data
        }).catch((error) => {
             console.log("Error in getCityWeather:", error)
             alert(`Could not obtain weather of ${city}!`)
        })
    })
    .catch((error) => {
        console.log("Error in getCityWeather:", error)
        alert(`Could not obtain latitude and longitude of ${city}!`)
    })
    

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search