id in this.unreadIds
doesn't do what you think it does. See the docs for the in operator. It will return true
if the object has the value as a property. So if this.unreadIds
had 3 items and you had an id of 1
, then the in
operator will return true
because 1
is a property of the array (this.unreadIds[1]
exists).
Instead, you should use includes.
Try rewriting your method like this:
checkIfNew(id) {
return this.unreadIds.includes(id);
}
Here's a working version of the component that updates the list without the Vuex store code:
<ul>
<li v-for="friend in user.friends" :key="friend.ids">
<span v-if="checkIfNew(friend.id)">{{ friend.name }}</span>
</li>
</ul>
export default {
data() {
return {
unreadIds: [5],
user: {
friends: [
{ id: 1, name: 'joe' },
{ id: 5, name: 'nancy' },
{ id: 9, name: 'sue' },
],
},
};
},
created() {
setTimeout(() => this.unreadIds.push(9), 2000);
},
methods: {
checkIfNew(id) {
return this.unreadIds.includes(id);
},
},
};
Just to prove here that David was correct all along, I put this code in a runable snippet, and cannot find any fault...
Vue.config.productionTip = false
new Vue({
el: '#app',
data() {
return {
unreadIds: [],
};
},
created() {
setTimeout(() => this.unreadIds.push(9), 2000);
},
methods: {
checkIfNew(id) {
// if(id in this.unreadIds) return true
// else return false
return this.unreadIds.includes(id);
},
},
computed: {
user(){
return {
friends: [
{ id: 1, name: 'joe' },
{ id: 5, name: 'nancy' },
{ id: 9, name: 'sue' }
]
}
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.js"></script>
<div id="app">
<ul>
<li v-for="friend in user.friends" >
<span v-if="checkIfNew(friend.id)">{{ friend.name }}</span>
</li>
</ul>
</div>
The sample above is a bit closer to the original question
- user is a computed not data
- unreadIds is initially empty
Upvote from me!