vuejs 2 nextTick() return - vuejs2

I'm trying to return some data using nextTick() in vuejs 2 as following
getProperty() {
this.$nextTick(function() {
return 'hello';
});
}
It doesn't work. Any clue?

this.$nextTick this function does not return anything; it just executes your callback after refreshing all new data.
so if you want to set some flag or data you can use modal/variable for that.
new Vue({
data: {
msg: 'hello'
},
methods: {
someTask: function () {
this.msg = 'hello next tick';
this.$nextTick(function() {
this.printVar();
});
},
printVar: function() {
// here this variable will be changed to latest value
// or call another function where this value is used
// this.anotherFunction();
console.log(this.msg);
}
},
ready: function () {
this.someTask();
}
});
or just let us know what you want to do with that so we can provide you better answer.

Related

How to format fetched data in Vue.js and update the vue instance

I am trying to fetch a json from an api and then format it for later use in google-charts.
I fetch the json-file using vue-resource and it works normally, the problem happens when I try to format the received data (update other arrays in data() with the fetched data), the vue component is not updated (the function is in created() ).
When I use a v-on:click the formating is done correctly but when I call the function from created it doesn't work.
I tried Vue.set and the splice method, both didn't work.
Goal
Getting the formatData() method to run and update the idArray.
export default {
name: 'app',
components: {
FirstCharts
},
data() {
return {
apiData: undefined,
idArray: []
}
},
created() {
this.loadApi();
},
methods: {
loadApi: function () {
this.$http.get('https://api.myjson.com/######').then(this.successCallback, this.errorCallback);
},
successCallback: function (response) {
this.apiData = response.data;
},
errorCallback: function (response) {
this.apiData = response.data;
this.formatData();
this.$forceUpdate();
},
formatData: function () {
for (var i = 0; i < this.apiData.resourcePlan.length; i++) {
this.idArray.splice(i, 1, parseInt(this.apiData.resourcePlan[i].resourceID));
Vue.set(this.idArray, i, parseInt(this.apiData.resourcePlan[i].resourceID));
}
}
it looks like you are calling formatData in the error callback, not the success callback. see if moving it into success works.

Why my vue js data member is not getting updated?

Data part
data () {
return {
containsAd: true
}
},
Method that manipulates the data member containsAd
updated () {
let _this = this
window.googletag.pubads().addEventListener('slotRenderEnded', function (event) {
if (event.slot.getSlotElementId() === 'div-gpt-ad-nativead1') {
_this.containsAd = !event.isEmpty // this is false
console.log('Ad Exists? ', _this.containsAd)
}
})
},
Just to check if the value has changed or not.
check () {
let _this = this
setTimeout(function () {
console.log('Current Value', _this.containsAd)
}, 5000)
}
Resulting Output
I think doing the event listener in the mounted hook will sort your issue.
data() {
return {
containsAd: true
};
},
mounted() {
window.googletag.pubads().addEventListener('slotRenderEnded', event => {
if (event.slot.getSlotElementId() === 'div-gpt-ad-nativead1') {
this.containsAd = ! event.isEmpty // this is false
console.log('Ad Exists?', this.containsAd);
}
});
}
Also using es6 shorthand function will avoid you having to set _this.

Cannot access Vue data set within mounted via ajax

I am using Vue2. I am getting json data via ajax in my mounted method. I then set that data to a data variable expecting to be able to access it from other methods outside of mounted, but all I get is an empty observable.
Any suggestions/advice? Thanks for the help.
var vm = new Vue({
el: '#app',
data: function () {
return {
allJson: []
};
},
methods: {
updateTableData: function(isActive) {
// cannot access this.allJson here
}
},
mounted: function() {
$.getJSON(Routes.USERS_GET_JSON, function(json) {
this.allJson = json;
});
}
});
I haven't used jQuery in a long, long time, but if I remember correctly you need to explicitly declare the context of this if you wish to use it within the callback, else you get something unexpected. However, I don't know if $.getJSON supports it even though it's a wrapper. So you can try the following:
$.getJSON(Routes.USERS_GET_JSON, function(json) {
this.allJson = json;
}, {
context: this
})
Or you can use .bind off of the function to scope this
$.getJSON(Routes.USERS_GET_JSON, function(json) {
this.allJson = json
}.bind(this))
Or if you're tranpsiling down with babel (which you probably are) you can use fat arrow syntax:
$.getJSON(Routes.USERS_GET_JSON)
.done( (json) => {
this.allJson = json
})
Or you can just alias this before the $.getJSON
let _self = this
$.getJSON(Routes.USERS_GET_JSON, function(json) {
_self.allJson = json
})
My guess is that this is not bound to your vue instance inside the callback function. Try the following
var vm = new Vue({
el: '#app',
data: function () {
return {
allJson: []
};
},
methods: {
updateTableData: function(isActive) {
// cannot access this.allJson here
}
},
mounted: function() {
const self = this;
$.getJSON(Routes.USERS_GET_JSON, function(json) {
self.allJson = json;
});
}
});

Computed filtering not working

So,I'm giving me first proper look at Vue.js since 2.0. And I'm having a hard time going from filter to computed.
Here is where I'm at (using vue-resource for the API call):
var moviesURL = 'http://localhost/api/movies';
var app = new Vue({
el: '#app',
data: {
liveFilter: '',
movies: ''
},
methods: {
getMovies: function() {
this.$http.get(moviesURL).then(response => {
this.movies = response.body;
}, response => {
console.log(response);
});
}
},
computed: {
filteredMovies: function() {
var self = this
return this.movies.filter(function(movie) {
return movie.indexOf(self.liveFilter) !== -1
});
}
},
created: function() {
this.getMovies();
}
});
And I keep getting those errors:
And I can't really my finger on what I'm doing wrong... Any idea?
You cannot filter over string. In your data movies should be an empty array, not empty string.
Also, be sure that response.body is an array too.
You initiate the movies as an empty string, and a string doesn't have a .find() method. Use an empty array instead

update data in component from Vue.directive

I have a directive that needs to update data in a Vue.component. How do I set the value? Here is my code:
Vue.directive('loggedin', function(value) {
console.log('loggedin = ' + value);
vm.$set('loggedIn', value);
});
vm.$set('loggedIn', value) does not work. I get the following error:
Uncaught TypeError: Cannot read property '$set' of undefined
var ck = Vue.component('checkout', {
template: '#checkout-template',
props: ['list'],
data: function() {
return {
loggedIn: '',
billingAddr: [],
shippingAddr: [],
}
},
});
The value being passed is 'true' or 'false'.
EDIT
I need to bind <div v-loggedin="true"></div> to my data value in the component and set that to 'true'. I do not need two-way binding.
Maybe I'm going about this the wrong way. Basically, I get a value for loggedin from the server and need to set my loggedIn value to true or false in the data on the component.
I'm not sure how you are using your directive, so I'm just going to make an assumption. Please correct me if I'm wrong.
Have a look at the twoWay property (you would probably need to use the object syntax though):
Vue.directive('loggedin', {
twoWay: true, // Setup the two way binding
bind: function () {
},
update: function (newValue) {
console.log('loggedin = ' + value);
this.set(newValue); // Set the new value for the instance here
},
unbind: function () {
}
});
Then you can use the directive like this (loggedIn is the property you want to write to afterwards, and which serves as the initial value as well):
<yourelement v-loggedin="loggedIn">...</yourelement>
Regarding your edit
Since you only want to pass data from your server to the component, you're much better of just using props:
var ck = Vue.component('checkout', {
template: '#checkout-template',
props: ['list', 'loggedIn'],
data: function() {
return {
billingAddr: [],
shippingAddr: [],
}
},
});
And then when using your component, pass it:
<checkout :loggedIn="true">
...
</checkout>
I have decided to go another route. There had to be a simpler way of doing this. So, here is what I did.
I am checking if a user is logged in by doing an ajax request through the 'created' function on the vm. I then update the auth variable in the vm with true or false.
var vm = new Vue({
el: 'body',
data: {
auth: false,
},
methods: {
getData: function() {
this.$http.get('{!! url('api/check-for-auth') !!}').then(function(response) {
this.auth = response.data;
}.bind(this));
},
},
created: function() {
this.getData();
},
});
In the component I created a props item called 'auth' and bound it to the auth data on the vm.
var ck = Vue.component('checkout', {
template: '#checkout-template',
props: ['list', 'auth'],
data: function() {
return {
user: [],
billingAddr: [],
shippingAddr: [],
}
},
});
And my component
<checkout :list.sync="cartItems" :auth.sync="auth"></checkout>
Thanks everyone for your help.