Isac Moura
Isac Moura

Reputation: 6878

Getter returning same value as the input value before action finish in Vue

I created a component and a module for a functionality X and I'm using Vuex for state management. The code works for the every first time insertion, but after this the Getter function always returns the same value of the input before the action ends and commit the mutation.

For example:
1 - everything is [0,0,0] and Getter is [0,0,0]. Insert 9 in the first position and the value is inserted.
2 - On the second time, the check if the value inserted is equal of what is on the state returns true, so we had to remove this verification.

By the way, the state continues to be modified without the action commit the changes to mutation, and when we look to the Getter (who retrieves the value from the state) the value inserted is already returned by the Getter.

Someone know how to fix this?

Here is the code

component:

Vue.component('profundidade-cell', {

    data: function () {
        return {
            valorProfundidade: [0, 0, 0],
            id: this.face + '-' + this.dente,
            ids: [
                this.face + '-profundidade-sondagem-' + this.dente + '-1',
                this.face + '-profundidade-sondagem-' + this.dente + '-2',
                this.face + '-profundidade-sondagem-' + this.dente + '-3'
            ],
            changedId: null,
            valorInserido: null,
            valorAnt: null,
        }
    },

    props: {
        arcada: String,
        sextante: String,
        dente: String,
        face: String,
        face_json: String,
        max_length: Number,
        min_value: Number,
        max_value: Number,
    },

    computed: {
        profundidadeSondagem() {
            return store.getters['profundidadeSondagem/profundidadeSondagem']({arcada: this.arcada,
                sextante: this.sextante, dente: "dente_" + this.dente, face: this.face_json});
        },

        presente() {
            return store.getters.dentePresente({arcada: this.arcada, sextante: this.sextante,
                dente: "dente_" + this.dente});
        }

    },

    created: function() {
        this.debouncedAlterarProfundidade = _.debounce(this.alterarValorProfundidadeSondagem, 400);
        this.$root.$on("vuex-carregado", this.carregar);
    },

    methods: {

        getValue(e) {
            this.changedId = e.target.id;
            this.valorInserido = e.target.value;

            this.debouncedAlterarProfundidade();


        },

        alterarValorProfundidadeSondagem() {

            let modelRefs = {};

            let patologia = {
                arcada: this.arcada,
                sextante: this.sextante,
                dente: "dente_" + this.dente,
                face: this.face_json,
                valor: this.valorProfundidade,
                modelRefs: modelRefs,
                id: this.changedId,
                valorInserido: this.valorInserido,
            };

            store.dispatch('profundidadeSondagem/MODIFY', patologia).catch(() => {

                this.valorProfundidade = this.profundidadeSondagem;
            })

        },

        carregar(){
            this.valorProfundidade = this.profundidadeSondagem;
        }

    },


    template: `
        <div>
            <input type="text" :id=ids[0] v-on:input.prevent="getValue($event)" :maxlength=max_length v-model=valorProfundidade[0] class="periograma-input col l4" v-bind:class="{ 'invisible': !presente }" />
            <input type="text" :id=ids[1] v-on:input.prevent="getValue($event)" :maxlength=max_length v-model=valorProfundidade[1] class="periograma-input col l4" v-bind:class="{ 'invisible': !presente }" />
            <input type="text" :id=ids[2] v-on:input.prevent="getValue($event)" :maxlength=max_length v-model=valorProfundidade[2] class="periograma-input col l4" v-bind:class="{ 'invisible': !presente }" />    
        </div>
    `

});

module:

const moduleProfundidadeSondagem = {
    namespaced: true,

    actions: {
        MODIFY({commit, dispatch, getters, rootGetters}, obj) {
            let patologia = {
                face: rootGetters.getNomeFace(obj.face),
                dente: rootGetters.getNomeDente(obj.dente),
                local: "FACE",
                ficha: this.state.idPeriograma,
                descricao: obj.valor.toString(),
                paciente: this.state.idPaciente,
                tipo: 'PROFUNDIDADE_DE_SONDAGEM'
            };

            if(obj.valor) != getters.profundidadeSondagem(obj)) {

                let reg = new RegExp(/([0-9],[0-9],[0-9])/);

                let param = null;

                return new Promise((resolve, reject) => {
                    if(obj.valor[0] == 0 && obj.valor[1] == 0 && obj.valor[2] == 0) {
                        param = axios.delete('/patologia', {data: patologia});
                    } else if (reg.test(obj.valor)){
                        param = axios.post('/patologia', patologia);
                    }

                    if(param != null) {
                        param.then(function (response) {
                            if(response.status == 200 || response.status == 201 && response.data) {
                                commit('armazenarProfundidadeSondagem', obj);

                                let dentes_data = {};
                                let face = '';

                                if (obj.arcada == 'arcada_superior' && obj.face == 'face_lingual_palatal') {
                                    face = 'palatina'
                                } else {
                                    face = obj.face.split('_')[1];
                                }


                                let classe_canvas = rootGetters.getNomeClasseCanvas(obj, face);

                                drawGraph(rootGetters.prepareDentesData(obj, face, dentes_data), face,
                                    classe_canvas);
                                resolve();
                            }

                        }).catch(error => {

                            store.dispatch('mensagemAlerta/ALERTA', {
                                tipo: 'error',
                                mensagem: 'Não foi possível cadastrar o nível de sondagem'
                            });

                            reject(error);
                        });
                    }
                })
            }
        },

        RESET_PROFUNDIDADE_SONDAGEM({commit}, ob) {
            commit('RESET_ALL', ob);
        }
    },

    getters: {
        profundidadeSondagem: (state, getters, rootState) => obj => {
            return rootState[obj.arcada][obj.sextante][obj.dente][obj.face].profundidade_sondagem;
        }
    },


Upvotes: 0

Views: 324

Answers (1)

Estradiaz
Estradiaz

Reputation: 3563

my guess is your issue lies here:


TL;DR - you pass your getter as valor to your action.


only a guess - as i cant debug your code


        store.dispatch('profundidadeSondagem/MODIFY', patologia).catch(() => {

            this.valorProfundidade = this.profundidadeSondagem;
        })

as you assign a reference from your rootState[...] and thus you change the properties of the rootState[...] in your component past the first run.

So your code then behaves like:

        let patologia = {
            arcada: this.arcada,
            sextante: this.sextante,
            dente: "dente_" + this.dente,
            face: this.face_json,
            
          // valor: this.valorProfundidade,
          ///* same as */ valor: this.profundidadeSondagem,
          /* same as */ valor: this.$store.getters['profundidadeSondagem/profundidadeSondagem'](...),
            modelRefs: modelRefs,
            id: this.changedId,
            valorInserido: this.valorInserido,
        };

A solution can be to this.valorProfundidade = this.profundidadeSondagem.slice(); as long it is an array or Object.assign({},...) - so you prevent the references

Upvotes: 1

Related Questions