1

I am making a weather app written in Vue.js, which fetches weather data periodically, but I have an issue rendering new data after the initial API call.

The empty data array is declared in the data, and a timer is used to fetch new data, as such:

      data() {
        return {
          weatherData: [],
          timer: '',
    };
  },

I have declared the data fetching in methods, as such:

methods: {
    async fetchWeatherData() {
      const response = await fetch("http://localhost:5002/timeseries");
      const data = await response.json();
      if (response.ok) {
        console.log("Data fetched sucssefully!");
      }
      return data;
    },

And when the app loads, the fetchWeatherData and setInterval is initiated:

  async created() {
     this.weatherData = await this.fetchWeatherData();
     setInterval(() => this.timer = this.fetchWeatherData(), 10000)

  },

The problem is that the new data is not rendered to the DOM, although new data is fetched successfully.

What would be the best step to ensure that the new data is rendered correctly upon successfull fetch?

-HK

8
  • You should check that the return value of the method fetchWeatherData is actually an Array. Commented Oct 4, 2021 at 9:13
  • I checked whether it is an array or not, and indeed it is an Array. Commented Oct 4, 2021 at 9:40
  • Well, then Vue will re-render the template as soon as you assign this array to weatherData Commented Oct 4, 2021 at 9:51
  • Alright, I figured out what is wrong. I am manipulating the data before it is rendered, i.e. I have a function that finds the highest and lowest temperatures for a given day. Basically, this function takes the weatherData-array and a day of interest as arguments and returns the max/min temperatures of the day. This function is not called upon new data from the API... What would be the best approach to call the function on new data? Commented Oct 4, 2021 at 10:16
  • 1
    If you can reproduce the issue on CodeSandbox - we will be able to assist you better. Commented Oct 4, 2021 at 14:05

2 Answers 2

1

In the component (or any container) where you render the weather data, add a key (like :key="renderWeatherKey"). Add renderWeatherKey to component data.

data() {
        return {
          weatherData: [],
          timer: '',
          renderWeatherKey: 0
    };
  },

In the method fetchWeatherData(), inside 'if' condition, add this.renderWeatherKey++ :

async fetchWeatherData() {
      const response = await fetch("http://localhost:5002/timeseries");
      const data = await response.json();
      if (response.ok) {
        console.log("Data fetched sucssefully!");
        this.renderWeatherKey++
      }
      return data;
    },

You can force the re rendered with that.

Sign up to request clarification or add additional context in comments.

3 Comments

This is quite an elegant suggestion, but unfortunately this did not solve my problem
@Hans-KristianNorumEidesen even with the :key="renderWeatherKey" in your component container? Strange, maybe because you need to wait for data ( const data = await response.json()) instead of response.ok ??
Yes, I had to wait for the data in n-th iteration (in the setInterval). Setting await in the setInterval-line was what solved the issue. Just FYI, your solution did work, but only with await was set properly. Again, I really found your suggestion to be quite beautiful :)
0

The solution, as posted by James Thomson over at the Vue forum, was to set the setInterval to async, since the fetch method also is async. See the full answer here.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.