LeBlaireau
LeBlaireau

Reputation: 17467

Using Ajax data inside Vue Component

I built some functionality which when I tried to export it to a vue component it stopped working.

I am almost certain it has to do with the ajax not being available when the component renders the template as the array is empty inside the template.

Can anyone see any way to delay the render until the ajax has loaded?

Maybe I am barking up the wrong tree. The data is available in the ajax .done() callback.

<template>

      <div   v-for="item in filteredItems"  @mouseover="activate" @mouseout="deactivate" @click="openlink"  class="item" :data-link="item.link">
      <div class="vline"></div>
        <div class="details">
          <div class="top">
            <div class="media">{{item.sectors}}</div>
            <div class="title">{{item.title}}</div>
          </div>
          <div class="description">{{item.description}}</div>
                </div>
                <div class="img">
                  <div class="overlay"><a class="button" v-bind:href="'featured/'+item.link">View project <span class="plus"><span>[</span><span>+</span><span>]</span></span></a></div>
                  <div v-if="context == 'home'">
                     <img class="workimg" v-bind:src="item.imagemobile">
                  </div>
                  <div v-else>
                     <img class="workimg" v-bind:src="item.imagemobile">
                  </div>


                </div>
    </div>
  </div>


</template>

  <script>
export default {
   props: ['context'],
    data() {
            return {
            work: [],
            }

  },


             computed: {

  filteredItems: function () {
    if (this.context == 'home') {
    return this.work.filter(function (works) {  return works});
  }
  else {
      return this.work.filter(function (works) {  return works});
  }
  },




},
  mounted() {

    self= this;
     $.ajax({
  method: "GET",
  url: "/work.json",
})
.done(function(data){
    self.work = data;
   console.log(self.work);
 // work has data!

  })
    .fail(function(xhr, status, error) {
       console.log(error)
    });

  }

    }


</script>

Edit:

It must have been the use of the this/self in the ajax function as the arrow syntax gets it working, this is strange because this look correct.

$.ajax({
        method: 'GET',
        url: '/work.json'
      })
      .done(data => {

        this.work = data;

      })
      .fail((xhr, status, error) => {

      })

Upvotes: 0

Views: 2271

Answers (1)

Existe Deja
Existe Deja

Reputation: 1379

A classic way to hide the render until a request is done is to add a isLoading property to your data. Notice that I'm using arrow function so I have access to the right context.

<template>
  <div>
    <p v-if="failed">Request failed</p>
    <p v-else-if="isLoading">Loading...</p>
    <div v-else>
      <!-- your content here -->
    </div>
  </div>
</template>

<script>
export default {
  data () {
    return {
      isLoading: false,
      failed: false,
      work: []
    }
  },

  mounted () {
    this.isLoading = true
    $.ajax({
      method: 'GET',
      url: '/work.json'
    })
    .done(data => {
      this.isLoading = false
      this.work = data
    })
    .fail((xhr, status, error) => {
      this.loading = false
      this.failed = true
    })
  }
}
</script>

But, several questions:

  • how did you register jquery in your app?
  • did you think about using pure XMLHttpRequest? Or even better with promises?
  • did you think about using vue-resource?

Upvotes: 3

Related Questions