Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to sort data in Vuex state with mutation

I have an array of objects that displays in a table on my html page in one of my Vue components. The array of objects is data in the state of a Vuex store.

export const store = new Vuex.Store({
    state: {
        jobs: [{...},{...},{...},{...},{...},{...}]
    },
    mutations: {
        sortJobs(state, sortKey) {
            console.log('running mutation');
            let compare = 0;
            this.state.jobs.sort((a, b) => {
                if (a.sortKey > b.sortKey) {
                    compare = 1;
                } else if (b.sortKey > a.sortKey) {
                    compare = -1;
                }
                return compare;
            });
        }
    },
    getters: {
        jobs: state => state.jobs
    }
});

I am trying to sort the array of objects in the mutation sortJobs, but it will not work. I am calling the mutation in one of my components.

methods: {
    sortBy: function(sortKey) {
        this.$store.commit('sortJobs', sortKey);
    }
}

This will not change the order of the array of objects, nor in my table. I've tested to see if I can do anything to the array of objects, and when I replace this.state.jobs.sort(...) with this.state.jobs.shift();, the first object element in the array disappears off of my table. But when it comes to sorting, I can't get this to sort at all. What am I doing wrong?

like image 724
aCarella Avatar asked Oct 25 '25 15:10

aCarella


1 Answers

Arrays are tricky in Vue. Take a look at these common gotchas.

Instead of mutating the array in place, try making a copy, sorting the copy and setting state.jobs to that sorted array.

Something like this:

  mutations: {
    sortJobs(state, sortKey) {
        console.log('running mutation');
        const jobs = this.state.jobs;
        jobs.sort((a, b) => {
            let compare = 0;
            if (a[sortKey] > b[sortKey]) {
                compare = 1;
            } else if (b[sortKey] > a[sortKey]) {
                compare = -1;
            }
            return compare;
        });
        state.jobs = jobs;
    }
  },

Also:

  • move the instantiation of the compare variable into the sort callback, so it'll be new each time you sort two list items.
  • instead of using a.sortKey, which will literally look for the sortKey property, use a[sortKey], which will let you access a variable attribute.

Working example, without vuex: https://jsfiddle.net/ebbishop/7eku4vf0/

like image 59
ebbishop Avatar answered Oct 27 '25 05:10

ebbishop