1

I'm working with a VueJS component (parent) that has a modal (child) in it. The latter is used to submit data then it should be automatically cleaned and closed and show the results on the parent page.

I use a form inside the modal, when is submitted it dispatches a store action and after that an event is emitted.

If I emit the event before dispatching, it works fine, but if I do it inside the then promise, nothing happens.

Parent Component

Template

<template>
<div>
    <div v-if="this.status !== 'loading'">
        [...]
        <v-dialog 
            v-model="modalAgregarCuenta"
            fullscreen
            hide-overlay
            transition="dialog-bottom-transition">
            <modal-agregar-cuenta 
                ref="modalAgregarCuenta"
                @closeModal="modalAgregarCuenta = false">
            </modal-agregar-cuenta>
        </v-dialog>
        [...]
    </div>
    [...]
</div>

Script

<script>
import ModalAgregarCuenta from './ModalAgregarCuentaBancaria';
[...]

export default {
    components: {
        'modal-agregar-cuenta': ModalAgregarCuenta,
        [...]
    },
    data() {
        return {
            modalAgregarCuenta: false,
            [...]
        }
    },
    watch: {
        [...]
        modalAgregarCuenta(){
            if( this.modalAgregarCuenta )
                this.$store.dispatch(TRACKER_EVENT, { "vm": this, "eventName": 'modal-bank-add-open'});
            else
                this.$store.dispatch(TRACKER_EVENT, { "vm": this, "eventName": 'modal-bank-add-close'});
        }
        [...]
    }
    [...]
}

Child Component

Template

<template>
<v-card>
    [...]
    <v-container>
        <v-form ref="formulario" v-model="validation" @submit.prevent="submitForm">
            [...]
        </v-form>
    </v-container>
</v-card>

Script

<script>
    [...]
    methods: {
        submitForm(){
            console.log(this); //<-- Second image
            //this.$emit('closeModal'); //<-- This line works properly

            if(!this.$refs.formulario.validate())
                return;

            this.$store.dispatch(BANK_CREATE_REQUEST, {
                cbu: this.cbu,
                legalNumber: this.accountInformation.legal_number
            })
            .then((res) => {
                this.$emit('closeModal'); //<-- This line does not
                console.log(this); //<-- Third image
                //this.closeModal();
                //this.clear();
                //this.closeModal();
                //this.$emit('closeModal');
                //this.$emit('closeModal');
                /*setTimeout(()=>{
                    //$this.closeModal();
                    this.$emit('closeModal');
                }, 2000);*/
            })
            .catch(err => err);
        },
        closeModal(){
            this.$emit('closeModal');
        },
        clear(){
            this.cbu = '';
            this.legalNumber = '';
        }
    }
    [...]
</script>

If I check Vue Devtools, it seems that the event is properly emitted as you can see in the following image:

enter image description here

I also noticed something weird when I use "console.log" function with "this" before and after dispatching. It's worth noting that the same component is logged in the console but some properties have different values:

Before

enter image description here

After

enter image description here

UPDATE

[BANK_CREATE_REQUEST]: ({commit}, {cbu, legalNumber}) => {
        commit(BANK_CREATE_REQUEST);
        commit(UI_LOADING, true);
        return apiCall.post(WE_API + '/v3/bank', {
            cbu: cbu,
            legal_number: legalNumber,
            legal_type: null
        })
        .then(res => {
            commit(BANK_CREATE_SUCCESS, res);
            commit(UI_LOADING, false);
            return res;
        })
        .catch(err => {
            commit(BANK_CREATE_ERROR);
            commit(UI_LOADING, false);
            throw err;
        })
    }
    
[BANK_CREATE_REQUEST]: (state) => {
    state.status = 'loading';
},
[BANK_CREATE_SUCCESS]: (state, payload) => {
    state.banks.push(payload.data.model);
    state.status = 'success';
},
[BANK_CREATE_ERROR]: (state) => {
    state.status = 'error';
},

Any help would be really appreciated.

Thank you.

6
  • Please show your BANK_CREATE_REQUEST action. My guess is that you aren't returning a promise or you are returning one that never resolves Commented Jul 15, 2021 at 1:22
  • 1
    FYI, event names should ideally by kebab-cased, ie close-modal instead of closeModal. See vuejs.org/v2/guide/components-custom-events.html Commented Jul 15, 2021 at 1:31
  • Thank you for your adivce with event names, I'll have it in mind. Regarding to the action, I've just updated the question, let me know if you need anything else. Thanks again!! Commented Jul 15, 2021 at 3:05
  • Everything looks good (unfortunately). Are you getting any errors? I'd change .catch(err => err) to .catch(err => console.error(err)) but your BANK_CREATE_ERROR mutations should already be letting you know if something did go wrong Commented Jul 15, 2021 at 3:15
  • 1
    Well, after struggling with this since yesterday, I found a Stack Overflow post with a similar issue (stackoverflow.com/questions/47519903/…). Unfortunately the problem was beyond our scope, it has to do with this line in the parent component "<div v-if="this.status !== 'loading'">". So when I changed v-if for v-show it worked properly. I think that it could be a framework bug or something like that. Commented Jul 15, 2021 at 17:02

1 Answer 1

-1

Please check the content of "this" - i think you won't find any content you'd expect, when you're inside the promise.

This should help you out:

let tempThis = this;
...
.then((res) => {
            tempThis.$emit('closeModal'); //<-- This line does work now

keep in mind that you could also use async/await (ES6) here, where this "problem" does not occur but you'd have to check the status of the response yourself so it would otherwhise not be that much easier to read or anything

Sign up to request clarification or add additional context in comments.

Comments

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.