Cannot access Vue data set within mounted via ajax - vue.js

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;
});
}
});

Related

VueJS - function in import js file not getting triggered

We are building a web application using Vue JS and PHP, we are new to Vue JS. The server-side execution is fine, the API is able to fetch data as JSON. While trying out a static array display before making the API call, we find that the function in imported "app.js" is not getting called and the table displayed is empty. Please let us know what we might be doing wrong. Appreciate your help.
import Vue from 'vue';
export const MY_CONST = 'Vue.js';
export let memberList = new Vue({
el: '#members',
data: {
members: []
},
mounted: function () {
this.getAllMembers();
},
methods: {
getAllMembers: function () {
/*
axios.get("https://xxxxxx.com/services/api.php")
.then(function (response) {
memberList.members = response.data.members;
});
*/
memberList.members = [{ "empname": "Dinesh Dassss" },
{ "empname": "Kapil Koranne" }];
}
}
});
This is the Vue component. The members object is empty.
<script>
import * as mykey from './app.js'
export default {
name: 'Home',
props: {
msg: String
},
data() {
return {
message: `Hello ${mykey.MY_CONST}!`,
members: mykey.memberList.members
}
}
};
</script>
You can also use this reference for current instance reference:
getAllMembers: function () {
var me = this;
/*
axios.get("https://xxxxxx.com/services/api.php")
.then(function (response) {
// direct this not works here but we have
//saved this in another variable and scope of a var is there
me.members = response.data.members;
});
*/
// this reference works fine here.
this.members = [{ "empname": "Dinesh Dassss" },
{ "empname": "Kapil Koranne" }];
}

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

Cant mount children component to ref

I have a problem with VuePaginator , that I can mount it to my Vue app $refs properties. I am doing everyting according to docs, here is my component in the html:
<v-paginator :resource.sync="comments" ref="vpaginator" resource_url="{{route('api.item.comments', $item->pk_i_id)}}"></v-paginator>
The pagination works correctly, but I can't trigger fetchData() from the vuejs code, because paginator is not getting mounted to vm.$refs.vpaginator.
Here is the code that I use:
var app = new Vue({
el: '#comments',
data : {
comments: [],
newComment: {
text: ""
}
},
components: {
VPaginator: VuePaginator
},
methods: {
addComment: function(comment){
var vm = this;
this.$http.post($('meta[name="item-url"]').attr('content'), comment)
.then(function(response){
toastr.success(response.data.result);
comment.text = "";
vm.$.vpaginator.fetchData();
}).catch(function (error) {
if(error.data){
toastr.error(error.data.text[0]);
}
})
},
logRefs: function(){
console.log(this.$refs.vpaginator);
}
}
});
I have created logRefs() function to check the $ref property and it is always undefined.
Since you are using the Version 1 of VueJS, usage is a bit different - check this demo http://jsbin.com/rupogesumo/edit?html,js,output
<v-paginator :resource.sync="comments" v-ref:vpaginator resource_url="{{route('api.item.comments', $item->pk_i_id)}}"></v-paginator>
Docs Reference: https://v1.vuejs.org/api/#v-ref

vuejs 2 nextTick() return

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.

Assign Vue-resource to a store

I am trying to store a resource in a store that can be shared between components according to the following documentation:
https://github.com/vuejs/vue-resource/blob/master/docs/http.md#response
http://vuejs.org/guide/application.html#State_Management
var App = Vue.extend({});
getcolleges = '/wp-json/wp/v2/schools-api?filter[posts_per_page]=9999';
var schoolFilter = Vue.extend({
template: '#school-filter-template',
data: function(){
return {
colleges: ''
}
},
ready: function() {
this.$http.get(getcolleges).then(function(colleges) {
this.$set('colleges', colleges.data);
})
},
});
However, when I try to create a store with the resource to use with other components, I get the following error: "The 'Data' option should be a function that returns a per-instance value in component definitions."
var App = Vue.extend({});
getcolleges = '/wp-json/wp/v2/schools-api?filter[posts_per_page]=9999';
var store = {
data: function(){
return {
colleges: ''
}
},
ready: function() {
vue.$http.get(getcolleges).then(function(colleges) {
vue.$set('colleges', colleges.data);
})
}
}
var schoolFilter = Vue.extend({
template: '#school-filter-template',
data: store
});