Reputation: 3797
I have my basic vue code that looks like this:
new Vue({
el : '#friendlist',
data : {
friends : []
},
methods : {
fetchStats : function(){
const axios_data = {
_token : $('meta[name="csrf-token"]').attr('content')
};
axios.post('/friend-stats/all', axios_data).then(response => {
this.friends = response.data;
});
}
},
mounted : function(){
this.fetchStats();
},
Now, for each friend
in the friends
array, I need to render a d3.js chart. I have a method in a different JS file that works correctly, it's called create_spider_chart(friend, target)
. The friend
variable contains a member of the friends array from our vue component above, and target
is the target element the chart should be appended to. This is where the problem arises.
If I do this in the response of the axios call:
this.friends = response.data.data;
let target;
for(let i=0;i<this.friends.length;i++){
target = '.spider-graphic-mini[data-id="'+this.friends[i].id+'"]';
create_spider_chart(this.friends[i], target); //d3.js
}
The element .spider-graphic-mini[data-id="'+this.friends[i].id+'"]
does exist in the HTML:
<template v-for="(friend,key) in friends">
<div class="col-md-6 friend-panel p-3">
<h5>@{{ friend.name }}</h5>
<div class="spider-graphic-mini mb-4" :data-id="friend.id"></div>
</div>
</template>
But, when I pass that identifier to the create_spider_chart
function, the element apparently doesn't exist. So $(target)
has length=0
and the function doesn't know where to create the chart.
How do I get around this?
Upvotes: 0
Views: 441
Reputation: 37803
Never used d3 so take this with grain of salt.
JS is single threaded and Vue DOM update process is asynchronous. The moment you assign content into your friends
array, Vue had no chance yet to render your template with new data. That's why your element doesn't exist yet.
What you need is to use $nextTick(callback)
to essentially way until Vue re-renders your template and run all the code depending on existence of elements inside the callback.
This piece of documentation explains it...
Upvotes: 1