Reputation: 2108
I'm trying to explore vuex, so what I'm trying to do is to get the count or an array when I remove or add values to it. Below are my codes.
home.vue template
<template>
<div :class="page.class" :id="page.id">
<h3>{{ content }}</h3>
<hr>
<p>Registered users count {{ unRegisteredUserCount }}</p>
<ul class="list-unstyled" v-if="getUnRegisteredUsers">
<li v-for="(unregistereduser, n) in getUnRegisteredUsers" @click="register(unregistereduser)">
{{ n + 1 }}
- {{ unregistereduser.id }}
{{ unregistereduser.fname }}
{{ unregistereduser.lname }}
</li>
</ul>
<hr>
<p>Registered users count {{ registeredUserCount }}</p>
<ul class="list-unstyled">
<li v-for="(registereduser, n) in getRegisteredUsers" @click="unregister(registereduser)">
{{ n + 1 }}
- {{ registereduser.id }}
{{ registereduser.fname }}
{{ registereduser.lname }}
</li>
</ul>
</div>
</template>
<script>
export default {
name: 'home',
data () {
return {
page: {
class: 'home',
id: 'home'
},
content: 'This is home page'
}
},
computed: {
getUnRegisteredUsers() {
if( this.$store.getters.getCountUnregisteredUsers ) {
return this.$store.getters.getAllUnRegisteredUsers;
}
},
getRegisteredUsers() {
if( this.$store.getters.getCountRegisteredUsers > 0) {
return this.$store.getters.getAllRegisteredUsers;
}
},
unRegisteredUserCount() {
return this.$store.getters.getCountUnregisteredUsers;
},
registeredUserCount() {
return this.$store.getters.getCountRegisteredUsers;
}
},
methods: {
register(unregistereduser) {
this.$store.commit({
type: 'registerUser',
userId: unregistereduser.id
});
},
unregister(registereduser) {
this.$store.commit({
type: 'unRegisterUser',
userId: registereduser.id
});
}
},
mounted: function() {
}
}
</script>
state.js
export default {
unRegisteredUsers: [
{
id: 1001,
fname: 'John',
lname: 'Doe',
state: 'Los Angeles',
registered: false
},
{
id: 2001,
fname: 'Miggs',
lname: 'Ollesen',
state: 'Oklahoma',
registered: false
},
{
id: 3001,
fname: 'Zoe',
lname: 'Mcaddo',
state: 'New York',
registered: false
},
{
id: 4001,
fname: 'Jane',
lname: 'Roberts',
state: 'Philadelphia',
registered: false
},
{
id: 5001,
fname: 'Ellen',
lname: 'Jennings',
state: 'Houston',
registered: false
},
{
id: 6001,
fname: 'Joseph',
lname: 'Reed',
state: 'Boston',
registered: false
},
{
id: 7001,
fname: 'Jake',
lname: 'Doe',
state: 'Portland',
registered: false
}
],
registeredUsers: []
}
getters.js
export default {
getAllUnRegisteredUsers(state) {
return state.unRegisteredUsers;
},
getAllRegisteredUsers(state) {
return state.registeredUsers;
},
getCountUnregisteredUsers(state) {
return state.unRegisteredUsers.length;
},
getCountRegisteredUsers(state) {
return state.registeredUsers.length;
},
getUserById(state) {
}
}
mutations.js
export default {
registerUser(state, payload) {
//find user
const user = _.find(state.unRegisteredUsers, {
'id': payload.userId
});
// remove user from original array
_.remove(state.unRegisteredUsers, {
'id': payload.userId
});
// set user object key value
user.registered = 'true';
// add user to new array
state.registeredUsers.push(user);
console.log(state.registeredUsers.length + ' - registered users count');
},
unRegisterUser(state, payload) {
//find user
const user = _.find(state.registeredUsers, {
'id': payload.userId
});
// remove user from original array
_.remove(state.registeredUsers, {
'id': payload.userId
});
// set user object key value
user.registered = 'false';
// add user to new array
state.unRegisteredUsers.push(user);
console.log(state.unRegisteredUsers.length + ' - unregistered users count');
}
}
During page load it renders the array count properly, but when I remove value to the registeredUsers and unRegisteredUsers the count is not updating. What am I missing here? Can anyone explain and what should I do to get the proper count? Thanks
Upvotes: 1
Views: 5984
Reputation: 10852
Modifying a list or an object in vuejs (as well as vuex) is tricky due to the limitation of JavaScript.
It seems that you are using lodash to remove items in an array. It will cause conflicts with vuejs's reactivity. See issue here.
If you're going to remove an item in an array, you'd better use splice
to do so.
Upvotes: 1
Reputation: 167
To add to For the Name's comments on removing stuff from an array, Use Vue.set when updating//adding to an array.
updateItem(state, payload) {
Vue.set(state.items, payload.index, payload.data);
}
See the documentation here: https://vuex.vuejs.org/guide/mutations.html#mutations-follow-vue-s-reactivity-rules
Upvotes: 4
Reputation: 2529
The reason this is not working is that you are mutating an array. Never mutate an array. You'll spend hours trying to troubleshoot why reactivity broke.
Replace a value with a new array in order to retain reactivity. Use _.filter or _.reject, like the example below.
state.registeredUsers = _.reject(state.registeredUsers, {
'id': payload.userId
});
The other answer by choasia is incorrect. Lodash is not the problem. Lodash is very helpful with Vuejs, you just need to use the functions that explicitly return a new array. See the Lodash docs under "returns" to know what it returns.
Upvotes: 2