bboy
bboy

Reputation: 1408

vuejs content rendering only after the first scroll (with axios)

My (vuejs) homepage contains the following:

template: <h3>{{ strings.home_headline }}</h3>

scripts:

data() {
    return {
      strings: []
    };
},
methods: {
    fetchData: function(){
      var self = this;

      // get translatable strings
      axios
        .get(MY_API_URL, {
          headers: { "X-Locale": self.locale }
        })
        .then(function(data) {
          self.strings = data.data;

          // This console works and outputs the right content; 
          console.log("strings: ", self.strings);
          // outputs the text that should come in the H3 
          console.log(strings.home_headline)
        })
        .catch(function(error) {
          console.log("Error", error);
        });
    }
},
created() {
    this.fetchData();
}

the console.log works but the template h3 is empty, UNTIL the first pixels scrolled, then everything is filled in with the text. what am i doing wrong here?

Upvotes: 1

Views: 115

Answers (2)

Patrick Artner
Patrick Artner

Reputation: 51623

Switching your member from array to object

return {
  // you need the fields here as well - an "empty" prepared object
  strings: { 
    home_headline: "", // more fields go here
  }  
};

and changing the lifecylcle-hook you are using should fix your problem:

async mounted() {
    await this.fetchData();
}

var app = new Vue({
  el: '#app',
  data() {    
    return {
      strings: { home_headline: ""}
    };
  },
  methods: {
    fetchData: function() {
      self = this;
      //will lead to error
      axios
        .get("error", {
          headers: {
            "X-Locale": self.locale
          }
        })
        .then(function(data) {
          self.strings.home_headline = "TATü"; 
        })
        .catch(function(error) {
          self.strings.home_headline = "TATö"; 
        });
    }
  },
  async mounted() {
    await this.fetchData();
  },
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.2/axios.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <h3>{{ strings.home_headline }}</h3>
</div>

For vue to enable the change-update you need to specify the fields on the object already.

Regarding the lifecycle hooks: in

created, templates and Virtual DOM have not yet been mounted or rendered. (https://www.digitalocean.com/community/tutorials/vuejs-component-lifecycle#creation-(initialization))

Upvotes: 4

Syed
Syed

Reputation: 16513

can you do this v-if="loading" in your <template>?

<template>
  <div v-if="loading">
    {{ strings }}
  </div>
<template>

your script

data() {
  return {
    loading: false,
    strings: [],
  };
},
created() {
  this.fetchData();
},
methods: {
  fetchData() {
    const self = this;
    self.loading = true;

    // get translatable strings
    axios
      .get(MY_API_URL, {
        headers: { 'X-Locale': self.locale },
      })
      .then((data) => {
        self.strings = data.data;
        self.loading = true;
      })
      .catch((error) => {
        console.log('Error', error);
      });
  },
},

Upvotes: 1

Related Questions