Home » vue » How to use List.JS with Vue + Axios?

How to use List.JS with Vue + Axios?

Posted by: admin November 26, 2021 Leave a comment

Questions:

I have used List.JS before successfully, but this time I’m trying to use it with a Vue.JS rendering of a list from JSON data.

I have a button at the top that when clicked should show only the QB position player.

Unfortunately I just get nothing, all list items are removed and I don’t get an error in the console so I’m not sure how to diagnose this.

Could it have something to do with the fact that the list elements aren’t prerendered/static html but injected using vue.js?

https://jsfiddle.net/nolaandy/hw2mheem/

HTML/Vue Template

<div id='app'>   
<div class="all-players-wrapper" id="all-player-listings">
<button id="filter-qb">QB</button>
<ul class="list">

  <li v-for="player in playerJSON">
    <div class="player-listing">
      <div class="player-left">
        <div class="player-name">{{player.firstName}} {{player.lastName}}</div>  
        <div class="playerPosition">{{ player.Position }}</div>
      </div><!-- end player-left -->
      <div class="player-right">
        <div class="player-grade">GRADE <span>{{player.NFLGrade}}</span></div>
      </div> <!--end player-right -->
    </div>
  </li>

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

JS

var vm = new Vue({ 
el: '#app',
data: {
status: 'Combine Particpants',
playerJSON: []
},
created: function () {
this.loadData();

},
methods: {
loadData: function () {
 var self = this;      
 axios.get('https://s3-us-west-2.amazonaws.com/s.cdpn.io/500458/tiny.json').then(function (response) {

   self.playerJSON = response.data
   console.log(response.data);
  })
  .catch(function (error) {
    self.status = 'An error occurred - ' + error
  });
  }
 }  
}); 

var options = {
valueNames: [ 'playerPosition' ]
};

var featureList = new List('all-player-listings', options);

$('#filter-qb').click(function() {
  featureList.filter(function(item) {
    if (item.values().playerPosition == "QB") {
    return true;
  } else {
    return false;
  }
});
 return false;
});
Answers:

As you suspected, List.js isn’t going to work properly if the DOM changes unpredictably. In this case, axios makes its call and populates the data after the (empty) List has been read into featureList.

Your example would work if you put the list-selecting-and-filtering code in the resolution of the axios call, but that’s not going to be a solution that works in a truly dynamic environment.

A custom directive will be called every time the DOM updates, so you can apply your adjustments consistently. Here’s a directive to apply a filter using List.js:

  directives: {
    filteredList(el, binding) {
      if (binding.value) {
        const options = {
          valueNames: ['playerPosition']
        };
        const featureList = new List(el, options);

        featureList.filter((item) => item.values().playerPosition === binding.value);
      }
    }
  }

Apply it like so:

<div class="all-players-wrapper" v-filtered-list="filterValue">

Add the filterValue data item, and have the button set it:

<button id="filter-qb" @click="() => filterValue='QB'">QB</button>

and you’re in business.

It’s worth noting that you could get the same effect by using a computed to filter the data, and you wouldn’t need an external library.

Updated fiddle