27
votes

I got a printerList computed property that should be re-evaluated after getPrinters() resolve, but it look like it's not.

sources are online: optbox.component.vue, vuex, optboxes.service.js

Component

<template>
    <div v-for="printer in printersList">
        <printer :printer="printer" :optbox="optbox"></printer>
    </div>
</template>
<script>
…
created() { this.getPrinters(this.optbox.id); },
    computed: {
        printersList() {
            var index = optboxesService.getIndex(this.optboxesList, this.optbox.id);
            return this.optboxesList[index].printers
        }
    },
    vuex: {
        actions: { getPrinters: actions.getPrinters,},
        getters: { optboxesList: getters.retrieveOptboxes}
    }
<script>

Actions

getPrinters({dispatch}, optboxId) {
    printers.get({optbox_id: optboxId}).then(response => {
        dispatch('setPrinters', response.data.optbox, response.data.output.channels);
    }).catch((err) => {
        console.error(err);
        logging.error(this.$t('printers.get.failed'))
    });
},

Mutations

setPrinters(optboxes, optboxId, printers) {
    var index = this.getIndex(optboxes, optboxId);
    optboxes[index] = {...optboxes[index], printers: printers }
},

Question

Why does the printerList computed property isn't re-evaluated (i.e. the v-for is empty)

3
Does the vuex debugger show the correct values for Printers? For me, it rings an alarm that mutations are passing the state around instead of handling it by themselves. - Hector Lorenzo
@HectorLorenzo if you mean the vue devtools tool,yes, but it's not commited - Édouard Lopez

3 Answers

29
votes

It is due to this line: optboxes[index] = {...optboxes[index], printers: printers }.

You are directly setting item with index, which can't be observed by Vue

Try splicing the old item from array and pushing the new one.

18
votes

You could do this:

Vue.set(optboxesList[index], 'printers', printers )
1
votes

you need force update

setPrinters(optboxes, optboxId, printers) {
    const index = this.getIndex(optboxes, optboxId);
    const newVal = {...optboxes[index], printers: printers }
    Vue.set(optboxes, index, newVal);
},