[Vue warn]: Error in render: "TypeError: _vm.stepProgression is not a function" - vuejs2

I'm creating a stepper component with a v-for loop, which currently works without an issues:
<li
v-for="(step, index) in stepper"
:key="step.id"
class="goals-modal__step"
:class="[{'is--selected': index === activeSlide }, {'is--visited': activeSlide > index}]"
>
{{ step.stage }}
</li>
Data object:
data: () => ({
activeSlide: 0,
}
This is working as expected.
However, when I try to pass the argument(index) from the v-for loop to a computed method so that I can return the class bindings for dynamic class logic (this will become more complex), I get an error: "[Vue warn]: Error in render: "TypeError: _vm.getClasses is not a function".
Updated code:
<li
v-for="(step, index) in stepper"
:key="step.id"
:class="stepProgression(index)"
>
{{ step.stage }}
</li>
And this is the computed method:
stepProgression(index) {
return {
'is--selected': index === this.activeSlide,
'is--visited': this.activeSlide > index
}
}
Does someone know what the issue us here? Any help much appreciated :)

Computed properties cannot receive arguments, so all you need to fix you code is move your property(function/method actually) to methods section like so:
methods: {
stepProgression(index) {
return {
'is--selected': index === this.activeSlide,
'is--visited': this.activeSlide > index
}
},
}

Related

Vue Checkbox filter component not working

In a single file component I made a checkbox array:
<label
v-for="(category, index) in categories"
:key="index"
>
<input type="checkbox" :value="category.value"
#change="emitSearchValue">
<span class="ml-2 text-gray-700 capitalize">{{ category.value }}</span>
</label>
With EventBus I transfer the data to the List component:
methods: {
emitSearchValue() {
EventBus.$emit('checked-value', 'this.checkedCategories')
}
}
In the List component I listen for the EventBus:
created() {
EventBus.$on('checked-value', (checkedCategories) => {
this.checkedvalue = checkedCategories;
})
}
Then my computed property look like this:
computed: {
filteredData() {
return this.blogs.filter(blog =>
// if there are no checkboxes checked. all values will pass otherwise the category must be included
!this.checkedCategories.length || this.checkedCategories.includes(blog.category)
)
}
},
In the console I get:
[Vue warn]: Error in render: "TypeError: Cannot read property 'length' of undefined"
Here is a link to a sandbox.
Whats wrong here?
Change the computed prop filteredData to:
computed: {
filteredData() {
if(!this.checkedvalue.length) return this.experiences
return this.experiences.filter(experience =>
this.checkedvalue.includes(experience.category)
);
}
}

VueJs/Nuxt Filter an array, error _vm.filtered.. is not a function

I am new to Vue/Nuxt and try to filter an array.
computed: mapState({
entries: state => state.archives.archives
}),
filteredArchive, function (objects, key) {
if (objects) {
return objects.filter(function(object) {
return object.tag === key
})
}
I want to get the result in a loop:
<li v-for="(entry, index) in (entries | filteredArchive('test'))">{{ entry.title }}</li>
This fails..
What is wrong in my approach..
Thanks for help.
I suggest creating a computed property for "filteredArchive" instead of a filter. In fact, I believe filters are going away in Vue 3. You can put it in a mixin if you need to share the logic across components.
ok. this is my solution for now:
<ul>
<li v-for="(entry, index) in filteredByTag(entries, 'test')">
<nuxt-link :to="'archive/' + entry.id">{{ entry.title }}</nuxt-link>
</li>
</ul>
computed: mapState({
entries: state => state.archives.archives,
}),
methods: {
filteredByTag(entries, tag){
return entries.filter((entry) => {
return entry.tag.match(tag)
})
}
},

DOM loading computed property before GET request is finished, how to delay?

I am working on a single page app (Vue-Cli). The DOM Is looking for a value before Vue is done with a GET request. Although the app/data loads fine, the browser gives me an annoying console error: Error in render: "TypeError: Cannot read property 'branch' of undefined".
Here's my Template/HTML code:
<template>
<div>
{{ branch[0].branch }}
</div>
</template>
Vue instance:
data() {
return {
branches: [],
issue: ''
}
},
async created() {
await this.getIssue()
await this.getBranches()
},
methods: {
async getIssue() {
this.issue = (await axios.getIssue(this.$route.params.id)).data[0]
},
async getBranches() {
this.branches = (await axios.getBranches()).data
}
},
computed: {
branch() {
return this.branches.filter(
branch => this.issue.branch === branch.branch_id
)
}
}
How would I correctly "wait" for the BRANCHES to finish loading and THEN filter the branches array and place it in the DOM?
Just use conditional rendering using v-if:
<div v-if="branch.length">
{{ branch[0].branch }}
</div>
https://v2.vuejs.org/v2/guide/conditional.html
Alternatively, use a ternary expression:
<div>
{{ branch.length ? branch[0].branch : '' }}
</div>

v-if doesn't recognize value from array of object

I'm working on a vueJS file and have a component :
<div class="panel-heading" v-on:click="displayValue(feature.id)">
{{ feature.nom }}
</div>
<div class="panel-body" v-if="getDisplay(feature.id)">
foo
</div>
my function displayValue(id) :
displayValue(id){
for(let i =0; i<this.product_site.displayFeatures.length;i++){
if (this.product_site.displayFeatures[i].idFeature === id){
this.product_site.displayFeatures[i].show = !this.product_site.displayFeatures[i].show
}
}
console.log(this.product_site.displayFeatures)
},
First I am not very happy with that. I trie to do a .find but it didn't work :
this.product_site.displayFeatures.find(function(a){
a.idFeature === id
}).show = true
But I had an error telling me can not read 'show' of undefined
and my function getDisplay(id)
getDisplay(id){
this.product_site.displayFeatures.forEach(function(a){
if(a.idFeature === id){
return a.show
}
})
}
same as before if I try with a find.
Anyway, I thought it would work with that, but when I do console.log(this.product_sites.displayFeatures) I have the array with the modified value but foo is not shown

VUEJS remove Element From Lists?

it is possible to remove specific element from lists. i tried this functions for remove element
pop() = remove last element
$remove(index) = not remove any element from lists
remove( index ) = undefined function
unshift( index ) = add new and empty element
splice( index ) = remove all element from index
please help me to remove specific element from lists.
below is my js code
var example2 = new Vue({
el: '#example-2',
data: {
items: [
{ message: 'Foo' },
{ message: 'Bar' },
{ message: 'Bar1' },
{ message: 'Bar2' },
{ message: 'Bar3' },
{ message: 'Bar4' }
]
},
methods : {
removeElement : function(index){
this.items.$remove(index);
}
}
})
below is my HTML code
<ul id="example-1">
<li v-for="(key, item) in items">
{{ item.message }}
<button v-on:click="removeElement(key)">remove</button>
</li>
</ul>
$remove is deprecated in Vue.js 2.0 and replaced by splice as stated in the docs. Make sure you add the 2nd parameter of splice for it to work.
Migration From Vue 1.x - 2.0
methods: {
removeElement: function (index) {
this.items.splice(index, 1);
}
}
You can use Vue.delete if your Vue version is 2.2.0+
Vue.delete(this.items, index);
The $.remove feature has been replaced with $.delete.
You can call it like so:
this.$delete(this.someItems, itemIndex).
It works on Object as well as Array. With objects, you need to use a keyed object. With arrays, you pass in the index of the item you want to delete.
Here is a fiddle example: https://jsfiddle.net/james2doyle/386w72nn/
EDIT
I added an example for an array as well
$delete can use inline in #click:
<ul id="example">
<li v-for="(item, key) in items">
{{ item.message }}
<button #click="$delete(items, key)">remove</button>
</li>
</ul>
https://v2.vuejs.org/v2/api/#vm-delete
Firstly, you should fix the methods key.
Then, you should pass the item to the $remove method, not the index. [ref]
https://jsfiddle.net/790og9w6/
If anyone wonders: $delete has been removed in VueJS 3 ( https://v3-migration.vuejs.org/breaking-changes/introduction.html#removed-apis ). Now it is possible to use javascripts native splice(index, count of objects to be deleted).