VueJs computed method error: Cannot read property 'words' of undefined"? - javascript

This is my pseudo code:
var vm = new Vue({
el: '#test',
data: {
words: [{name:'1'}, {name:'2'}, {name:'3'},{name:'4'},{name:'5'},{name:'6'}],
},
computed: {
paginatedWords: function (words) {
return vm.words.slice(2, 2);
}
}
});
I want to show only a portion of words with v-for,
Here is the Html:
<ul>
<li v-for="w in paginatedWords"> #{{w.name}} </li>
</ul>
But console gives me this error :
Error in render function: "TypeError: Cannot read property 'words' of
undefined"
What am I doing wrong?

Use this, not vm.
paginatedWords: function () {
return this.words.slice(2, 2);
}
Also, slice(2,2) will return an empty array. The first argument is where to start and the second is where to end. See slice.
Finally, the words argument is ignored.
var vm = new Vue({
el: '#test',
data: {
words: [{
name: '1'
}, {
name: '2'
}, {
name: '3'
}, {
name: '4'
}, {
name: '5'
}, {
name: '6'
}],
},
computed: {
paginatedWords: function() {
return this.words.slice(2, 4);
}
}
});
<script src="https://unpkg.com/vue#2.2.6/dist/vue.js"></script>
<div id="test">
<ul>
<li v-for="w in paginatedWords"> {{w.name}} </li>
</ul>
</div>

Related

How to v-for checked value

I'm trying to create a checkbox select only one.
<div id="app">
<div v-for="(question, index) in questions">
<input type="checkbox" value="question.value" v-model="additional_grouped" #change="uniqueCheck"> {{question.title}}
</div>
{{ result }}
</div>
My JS looks like the following:
new Vue({
el: '#app',
data() {
return {
additional: [],
additional_grouped: [],
questions: [
{
title: 'A',
value: 0
},
{
title: 'B',
value: 1
},
{
title: 'C',
value: 2
}
]
}
},
computed: {
result: function(){
return this.additional.concat(this.additional_grouped);
}
},
methods: {
uniqueCheck(e){
console.log(e)
this.additional_grouped = [];
if (e.target.checked) {
this.additional_grouped.push(e.target.value);
}
}
}
});
This is the old result.
I'm trying to get results like this.
I can do this by not the v-for method, but I want to do it this way. Because I have a lot of data, How can I checked value in v-for?
Here is my pen: enter link description here
You are missing the value binding (:value), here's your example fixed:
new Vue({
el: '#app',
data() {
return {
additional: [],
additional_grouped: [],
questions: [
{
title: 'A',
value: 0
},
{
title: 'B',
value: 1
},
{
title: 'C',
value: 2
}
]
}
},
computed: {
result: function(){
return this.additional.concat(this.additional_grouped);
}
},
methods: {
uniqueCheck(e){
this.additional_grouped = [];
if (e.target.checked) {
this.additional_grouped.push(e.target.value);
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div v-for="(question, index) in questions">
<input type="checkbox" :value="question.value" v-model="additional_grouped" #change="uniqueCheck"> {{question.title}}
</div>
{{ result }}
</div>
Documentation
uses :value="question.value" instead of value="question.value"
new Vue({
el: '#app',
data() {
return {
additional: [],
additional_grouped: [],
questions: [
{
title: 'A',
value: 0
},
{
title: 'B',
value: 1
},
{
title: 'C',
value: 2
}
]
}
},
computed: {
result: function(){
return this.additional.concat(this.additional_grouped);
}
},
methods: {
uniqueCheck(e){
this.additional_grouped = [];
if (e.target.checked) {
this.additional_grouped.push(e.target.value);
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div v-for="(question, index) in questions">
<input type="checkbox" :value="question.value" v-model="additional_grouped" #change="uniqueCheck"> {{question.title}}
</div>
{{ result }}
</div>
If you want to get an array of the values of checked boxes, you should just do this
<div id="app">
<div v-for="(question, index) in questions" :key="index">
<input type="checkbox" v-model="question.checked"> {{question.title}}
</div>
{{ result }}
</div>
and
new Vue({
el: '#app',
data() {
return {
questions: [
{
title: 'A',
value: 0
},
{
title: 'B',
value: 1
},
{
title: 'C',
value: 2
}
]
}
},
computed: {
result: function(){
return this.questions.filter(q => q.checked).map(q => q.value)
}
}
});

TypeError: this.$refs.datasource.fetch is not a function

I am trying to call the fetch method on a data source created with a vue wrapper.
The error is [Vue warn]: Error in mounted hook: "TypeError: this.$refs.datasource.fetch is not a function" So my question is how can I call methods from the $refs object.
I made a stackblitz here
<body>
<div id="vueapp" class="vue-app">
<kendo-datasource ref="datasource" :data="dataSourceArray">
</kendo-datasource>
</div>
</body>
new Vue({
el: '#vueapp',
data: function() {
return {
dataSourceArray: [
{ text: 'Albania', value: '1' },
{ text: 'Andorra', value: '2' },
{ text: 'Armenia', value: '3' },
{ text: 'Austria', value: '4' },
{ text: 'Azerbaijan', value: '5' },
{ text: 'Belarus', value: '6' },
{ text: 'Belgium', value: '7' }
]
}
},
mounted: function () {
this.$refs.datasource.fetch()//<== error here
}
})
The ref you are getting is the entire <kendo-datasource> component, which does not directly have a fetch() method. I believe what you are trying to do is get the kendoDataSource within the component and call the fetch method on it, which would be:
this.$refs.remoteDatasource.kendoDataSource.fetch();
modifying your example to see it in action:
<kendo-datasource
ref="datasource"
:data="dataSourceArray"
:type="'odata'"
:transport-read-url="'https://demos.telerik.com/kendo-ui/service/Northwind.svc/Customers'">
</kendo-datasource>
this.$refs.remoteDatasource.kendoDataSource.fetch(function(){
var data = this.data();
console.log(data[0]);
});
}

Uncaught TypeError: not a function when calling method from data in Vue

I get an error: "Uncaught TypeError: this.thePerson is not a function" when I run this:
var myApp = new Vue({
el: "#app",
data: {
person: [this.thePerson()]
},
methods: {
thePerson: function() {
return {
personNickname: "Bob",
personOwes: 0,
paymentType: {
card: true,
cash: false
}
};
}
}
});
I can't figure out why!
P.S. I realize this is weird looking code but there's a reason why I'm using a function to return the array contents...
Turn data into a function.
var myApp = new Vue({
el: "#app",
data: function() {
return {
person: [this.thePerson()]
}
},
methods: {
thePerson: function() {
return {
personNickname: "Bob",
personOwes: 0,
paymentType: {
card: true,
cash: false
}
};
}
}
});
Do you try, assigning persons value on Vue's created method ?
according to your example:
var myApp = new Vue({
el: "#app",
data: {
person: []
},
methods: {
thePerson: function() {
return {
personNickname: "Bob",
personOwes: 0,
paymentType: {
card: true,
cash: false
}
};
}
},
created(){
this.person.push(this.thePerson())
}
});

Vue.js inline template not displaying data

I am trying to use an inline-template in Vue.js but I can't get it to display data, here is my code:
Vue.component('food-item', {
props: ['food'],
})
var app7 = new Vue({
el: '#app-7',
data: {
foodList: [
{ id: 0, text: 'Vegetables' },
{ id: 1, text: 'Cheese' },
{ id: 2, text: 'Whatever else humans are supposed to eat' }
]
}
})
HTML Code:
<div id="app-7">
<ol>
<food-item v-for="item in foodList" v-bind:food="item" v-bind:key="item.address">
</food-item>
</ol>
<!-- template -->
<food-item inline-template>
<li>{{ food.text }}</li>
</food-item>
</div>
I get the following error:
TypeError: Cannot read property 'text' of undefined
You're treating it as a way of specifying the template separate from the component. That's not how inline-template works. The inline-template attribute and the template specification go in the tags where you're instantiating the component.
Vue.component('food-item', {
props: ['food'],
})
var app7 = new Vue({
el: '#app-7',
data: {
foodList: [{
id: 0,
text: 'Vegetables'
},
{
id: 1,
text: 'Cheese'
},
{
id: 2,
text: 'Whatever else humans are supposed to eat'
}
]
}
})
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>
<div id="app-7">
<ol>
<food-item v-for="item in foodList" v-bind:food="item" v-bind:key="item.address" inline-template>
<li>{{ food.text }}</li>
</food-item>
</ol>
</div>

Use vue.js methods with select2 directive

I've create a new directive to use the jQuery Plug-In Select2 with vue.js as written down on the vue.js example page.
But I don't want to just output the value of the selected option. To store the selections I try to bind my custom method create to the #change event.
Inside the directive, the Select2 will trigger the change event for the select input field while it updates, but nevertheless it still doesn't call my custom method.
Is there some hidden magic? I've tried to read the source code of vue.js but can't find something that puts me in the right direction.
Vue.directive('select', {
twoWay: true,
priority: 1000,
params: ['options'],
bind: function() {
var self = this;
$(this.el)
.select2({
data: this.params.options
})
.on('change', function() {
self.set(this.value);
});
},
update: function(value) {
$(this.el).val(value).trigger('change');
},
unbind: function() {
$(this.el).off().select2('destroy');
}
});
var vm = new Vue({
el: '#items',
data: {
items: [],
new_item: '',
options: [{
id: 1,
text: 'First'
}, {
id: 2,
text: 'Second'
}, {
id: 3,
text: 'Third'
}, {
id: 4,
text: 'Fourth'
}, {
id: 5,
text: 'Fifth'
}]
},
methods: {
create: function() {
var self = this,
label = '';
this.options.map(function(item) {
if (self.new_item == item.id)
label = item.text;
});
var obj = {
id: self.new_item,
name: label
};
this.items.push(obj);
this.new_item = '';
}
}
});
select {
min-width: 300px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/vue/1.0.24/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/select2.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/css/select2.min.css" rel="stylesheet" />
<div id="items">
<ul>
<li v-for="item in items">{{ item.id }} – {{ item.name }}</li>
</ul>
<select v-select="new_item" #change="create" :options="options">
<option value="0">--Select--</option>
</select>
</div>
Maybe you can add watcher to your new_item variable like this. So you can do something when new_item value change.
I myself still searching how to trigger #change after select2 change method, but no clue til now.
Vue.directive('select', {
twoWay: true,
priority: 1000,
params: ['options'],
bind: function() {
var self = this;
$(this.el)
.select2({
data: this.params.options
})
.on('change', function() {
self.set(this.value);
});
},
update: function(value) {
$(this.el).val(value).trigger('change');
},
unbind: function() {
$(this.el).off().select2('destroy');
}
});
var vm = new Vue({
el: '#items',
data: {
items: [],
new_item: '',
options: [{
id: 1,
text: 'First'
}, {
id: 2,
text: 'Second'
}, {
id: 3,
text: 'Third'
}, {
id: 4,
text: 'Fourth'
}, {
id: 5,
text: 'Fifth'
}]
},
methods: {
create: function() {
var self = this,
label = '';
this.options.map(function(item) {
if (self.new_item == item.id)
label = item.text;
});
var obj = {
id: self.new_item,
name: label
};
this.items.push(obj);
this.new_item = '';
}
},
watch:{
new_item:function(){
alert(this.new_item);
}
}
});
select {
min-width: 300px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/vue/1.0.24/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/select2.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/css/select2.min.css" rel="stylesheet" />
<div id="items">
<ul>
<li v-for="item in items">{{ item.id }} – {{ item.name }}</li>
</ul>
<select v-select="new_item" #change="create" :options="options">
<option value="0">--Select--</option>
</select>
</div>

Categories

Resources