0

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) => {

      })
6
  • What error are you encountering? Commented Jun 28, 2017 at 10:37
  • The template is not rendering because there is no data. Commented Jun 28, 2017 at 10:38
  • The template should render when the data is retrieved. Is that the first line of your template? The div with v-for? Commented Jun 28, 2017 at 10:39
  • Hi Bert, tried this but that is not it because console.log( this.work); inside the computed "filteredItems" is empty. Commented Jun 28, 2017 at 10:53
  • That's true, it will be empty initially. And when your Ajax completes it will be called again. Commented Jun 28, 2017 at 10:59

1 Answer 1

3

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?
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks George, I am adding jquery in my man app var $ = require('jquery');
I will look into vue-resource
@LeBlaireau There's no reason to switch to vue-resource if you're comfortable with jquery for Ajax. Yes you are already using promises.
will mark this up as it got me partially to the solution! :) I did not need the is.loading but the arrow syntax did it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.