Reputation: 15
I am trying to access the data from a child array and use that in my v-if
Here is my data and my code. Any help would be great, even just links to the correct documentation.
<div class='post' v-for="message in messages" v-if='["Food","Featured"].includes(tag) || tag === ""'>
<h2>{{message.text}}</h2>
<div v-for="category in message.categories">
{{category.name}}
</div>
</div>
instead of
v-if='["Food","Featured"]
I have been trying v-if='[category in message.categories]
Obviously that is not correct, but how do you correctly send data from a nested array UP to the v-if
statement?
data is here:
[
{
"text":"Featured food content",
"categories":[
{
"name":"Featured",
"ID": "189"
},
{
"name":"Food",
"ID": "190"
}
]
},
{
"text":"Featured content",
"categories":[
{
"name":"Featured",
"ID": "189"
}
]
}
]
Thank you for all the help. This my solution until I can learn how to use computed properties correctly.
<template v-for="message in messages">
<div class='post' v-if='message.categories.map(c => c.name).includes(tag) || tag === ""'>
<h2>{{message.text}}</h2>
<div v-for="category in message.categories">
{{category.name}}
</div>
</div>
</template>
Upvotes: 0
Views: 951
Reputation: 2342
(This answer disregards the issue with using both v-for
and v-if
at the same time, which is discussed quite well here: https://stackoverflow.com/a/54531252/1406083)
If you want to check the category names, you can use .map(...)
on your array, which will return a new array that you can then call .includes(tag)
on. Put this in your v-if
:
tag === "" || message.categories.map(c => c.name).includes(tag)
Upvotes: 0
Reputation: 1290
Here's something that might do what you want, let me know. I couldn't tell exactly what your problem was from your code.
<div id="app">
<div
v-for="message in messages"
v-if="messageHasCategory(message, currentCategory)"
>
{{message.text}}
</div>
</div>
const app = new Vue({
el: "#app",
data: {
currentCategory: 'Food',
messages: [{
text: 'Food message',
categories: [{
name: "Food"
}]
}, {
text: 'Featured message',
categories: [{
name: "Featured"
}]
}]
},
methods: {
messageHasCategory(message, categoryName) {
return message.categories.find(c => {
return c.name == categoryName;
})
}
}
})
Or you can combine the v-for and v-if into a single computed property like @zerbene suggests.
<div id="app">
<div v-for="message in currentCategoryMessages">
{{message.text}}
</div>
</div>
const app = new Vue({
el: "#app",
data: {
currentCategory: 'Food',
messages: [{
text: 'Food message',
categories: [{
name: "Food"
}]
}, {
text: 'Featured message',
categories: [{
name: "Featured"
}]
}]
},
computed: {
currentCategoryMessages() {
return this.messages.filter(m => {
return m.categories.map(c => c.name).includes(this.currentCategory);
})
}
},
})
Codepen: https://codepen.io/dyllandry-the-styleful/pen/vYKEjeb
Upvotes: 1
Reputation: 1492
Warning: v-for and v-if not working together in Vue.js. For the v-if, you need to transform it as COMPUTED properties like
this.data is your nested data that you have declared. In filter() you write your test.
computed: {
testedValues: function () {
return this.data.filter(i => i.categories !== '')
}
}
and after you write what you want
<div v-for="item in testedValues">{{item}}</div>
Upvotes: 2