Search code examples
javascriptvue.jsgraphqlnuxt.jsapollo

How to fetch data from API to a dynamic API URL before page loads (empty value problem)


I am a beginner in javascript and vue. I am using dynamic routes and I am trying to pass data from my local API (Graphql via Apollo) to Openweathermap API URL on page load. The issue is that openweather API returns 400 because the URL is passed an empty value (this.city) unless I refresh the page. I have not been able to figure out how I can fetch the value (the name of the city) from my local API before axios (or fetch) is trying to fetch any data from openweather API.

In a nutshell: this.city is passed as an empty value to axios URL which returns 400 error from API unless I refresh the page (which doesn't always work either).

This is my code:

<script>
  import venueQuery from '~/apollo/queries/venue/venue'


  export default {
    data() {
      return {
        loading: 0,
        venues: [],
        city: '',
        sunset: '',
        currentTemp: ''
      }

    },

    apollo: {
      $loadingKey: 'loading',
      venues: {
        prefetch: true,
        query: venueQuery,

        variables() {
          return {
            slug: this.$route.params.slug
          }
        },
        result(result) {
          return this.city = result.data.venues[0].temperature

        }
      }
    },

    created() {

      this.getWeatherInfo()

    },

    methods: {
      getWeatherInfo() {
        this.$axios
          .$get(`${process.env.WEATHER_BASEAPI}${this.city}${process.env.WEATHER_KEY}`).then(data => {
            this.currentTemp = Math.floor(data.main.temp - 273.15);
            this.sunset = new Date(data.sys.sunset * 1000).toLocaleTimeString("en-GB").slice(0, 5)
          })
      }
    }
  }

</script>

Any help would be appreciated.


Solution

  • Since city is populated asynchronously after the component is created, getWeatherInfo() (in the created hook) would be called before city is actually set.

    You could add a watcher on city so that any updates to the data property would cause getWeatherInfo():

    export default {
      watch: {
        city() {
          this.getWeatherInfo()
        }
      }
    }