Search code examples
vue.jsvuex

vue watch mapState not working


I use a store value in my component and try to update it.The store value gets changed when I click the button, but the change is not reflected in the component output (i.e. {{query}})

    <template>
         span {{query}}
         button(@click='updateQuery')
    </template>

    <script>
    export default {
        computed: mapState('map', [
            'query'
        ]),
        methods: {
            ...mapMutations('map', [
                'setStart'
            ]),
            updateQuery() {
                this.setStart(new Date());
            }
       }
   }
   </script>

store:

export default {
    namespaced: true,
    state: {
        query: {},
        start: null,
        end: null
    },
    mutations: {
        setQuery(state, value) { state.query = value },
        setStart(state, value) {
            state.start = value;
            state.query.timestamp = state.query.timestamp ? state.query.timestamp : {};
            state.query.timestamp.$gte = value;
        },
        setEnd(state, value) {
            state.end = value;
            state.query.timestamp = state.query.timestamp ? state.query.timestamp : {};
            state.query.timestamp.$lte = value;
        },
    }
}

Solution

  • The issue here is Vue cannot detect that you are adding new properties to the query object dynamically.

    In this code:

    state.query.timestamp = state.query.timestamp ? state.query.timestamp : {};
    

    You are adding a timestamp property to query that was not previously there. It will not, therefore, be reactive. In order to work with Vue properly you need to use Vue.set.

    Vue.set(state.query, `timestamp`, state.query.timestamp ? state.query.timestamp : {})
    

    Note, you will also need to do that on the next line for the $gte property.

    Alternatively, you could initialize query object.

    state: {
        query: {
          timestamp:{
            $gte: null,
            $lte: null
          }
        },
        start: null,
        end: null
    },