1

I have a code which need to get some processed values from Vuex store. So I wrote getter which should return processed values. The code looks like:

    mediaSettings: (state) => {
        const timestamps = [];
        const events = [];

        state.media.forEach( medium => {
            if( !medium.settings || !medium.settings.dates ) return;

            medium.settings.dates.forEach( dateRange => {
                if( !dateRange.date_from || !dateRange.date_to ) return;

                const from = new Date( dateRange.date_from );
                const to = new Date( dateRange.date_to );
                while ( from <= to ) {
                    if( timestamps.includes(from.getTime()) ) {
                        from.setDate( from.getDate() + 1 );
                        continue;
                    }

                    events.push({
                        date: new Date( from.getTime() ),  // Need Date clone via new Date().
                        mediumId: medium.id,
                    });
                    timestamps.push( from.getTime() );
                    from.setDate( from.getDate() + 1 );
                };
            });
        });
        return events;
    }

This is the muttation which change the values:

SET_MEDIA_SETTINGS(state, payload) {
    state.media.forEach( medium => {
        if( medium.id === payload.media_id ) {
            medium.settings = { timeMode: payload.mode, dates: payload.dates, times: payload.times };
        }
    });
},

The problem is that Vuex does not react when state.media[].settings.dates[] values are changed. The change should happened on state.media[] level. How can I fix it? What is the workaround for this issue? Thanks for help.

1 Answer 1

1

The solution for this was to use Vue set() method to change the value in mutation. The code is here:

SET_MEDIA_SETTINGS(state, payload) {
    state.media.forEach( (medium, index) => {
        if( medium.id === payload.media_id ) {
            medium.settings = { timeMode: payload.mode, dates: payload.dates, times: payload.times };
            this._vm.$set(state.media, index, {...medium});
        }
    });
},
Sign up to request clarification or add additional context in comments.

4 Comments

I think this is an anti-pattern; you are manipulating the state object in situ which defeats the whole point of Vuex and the Redux pattern. You should be creating a new object/array with the mutations and then replacing state.media with the mutated object.
It could be right and should work too, but this is the solution recomanded by documentation. Thanks for the comment.
But I thing the code which will replace whole state.media object would be longer than this.
does it replay properly through the Vue Devtool time machine. If so then go for it, otherwise understand that although it works in your example it may not be the 'correct' solution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.