Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wait for Ajax response data in Vue.js

I have a Vue component where I am trying to fetch some data from an API using axios.

<template>
    <div>
        This is Default child component
        {{tools[0].name}}
    </div>
</template>

<script>
import { CustomJS } from '../js/custom.js';

export default {
  name: 'HomeContent',
  props: {
    tools: []
  },
  methods: {
      fetchData() {
        const customJs = new CustomJS();
        return customJs.getTools();
      }
  },
  created() {
    this.tools = this.fetchData(); //preferably need to wait here wait for response
  }
}
</script>

The getTools() function is in a different JS file outside the Vue component file which makes the API call using axios.get.

getTools(id = 0){
    this.apiTool += (id > 0) ? id : '';
    axios.get(this.apiTool, {
    })
    .then(function (response) {
        console.log(response.data);
        return response.data;
    })
    .catch(function (error) {
        console.log(error);
    });
}

The problem is, {{tools}} is undefined since the getTools() takes some time to return the response data. How can wait for the response data and then return?

like image 815
Display name Avatar asked Jul 13 '18 09:07

Display name


3 Answers

Try the code below: so the code will render only when its actually loaded

<div v-if="tools">
    This is Default child component
    {{tools[0].name}}
</div>
like image 166
Surya Neupane Avatar answered Oct 10 '22 09:10

Surya Neupane


Usually for that, I am using a loader to show the user that a request is in progress

<div v-if="loading">
  <loader /> //a loader component
</div>

<div v-else>
  // show the template since request finished
</div>

and the script

export default {
  data: () => ({
    loading: false
  }),

  created() {
   this.loading = true
   axios.get('api') //your request
   .then(response => console.log(response))
   .finally(() => (this.loading = false)) //when the requests finish
  }

}

If you don't like the way above, you can use beforeEnter so the route will load only when the request finishes:

{
  path: '/my-route',
  component: YourComponent,
  props: true,
  beforeEnter (to, from, next) {
    axios.get('api-request')
     .then(response => {
      to.params.data = response //we pass data through props to the component
      next()
     })
  }
}
like image 33
Roland Avatar answered Oct 10 '22 09:10

Roland


<template>
    <div v-if="isGetTools">
        This is Default child component
        {{tools[0].name}}
    </div>
</template>

<script>
import { CustomJS } from '../js/custom.js';

export default {
  name: 'HomeContent',
  props: {
    tools: []
  },
  data: function () {
    return {
      isGetTools: false
    }
  },
  methods: {
      fetchData() {
        const customJs = new CustomJS();
        this.tools = customJs.getTools();
        this.isGetTools = true;
      }
  },
  created() {
    this.fetchData(); //preferably need to wait here wait for response
  }
}
</script>

Try to add v-if in your div. And update the isGetTools to true after getting the result from AXIOS

like image 22
markcc Avatar answered Oct 10 '22 07:10

markcc