Search code examples
javascriptvue.jseventsvuejs2eventemitter

VueJS - Run Code after event is successfully emitted


I'm trying to clear up the form in the child component after the event containing the entered form data has been successfully passed from the child to parent component. However, I notice that the form gets cleared before the data gets propagated via the event to the parent component, such that the event passes empty values to the parent. I tried delaying the clearForm() using a timeout, but it didn't help. Is there a way to modify the behavior such that the clearForm() happens only after the event completes and the data has been saved?

Attached is the code.

Child Component

<template>
    <!-- Contains a form -- >
</template>

<script>
export default {
    
    data() {
        return {
            additionalInfo: 
                {
                    id: new Date().toISOString(),
                    fullName: '',
                    preAuthorize: '',
                    serviceAddress: ''
                },
            validation: {
                fullNameIsValid: true,
                serviceAddressIsValid: true
            },
            formIsValid: true,
            addServiceButtonText: '+ Add Service Notes (Optional)',
            serviceNotes: [],
            showServiceNotes: false,
            enteredServiceNote: '', //service notes addendum
        }
    },
    computed : {
        // something
    },
    methods: {
        
        setServiceNotes(){
            this.showServiceNotes = !this.showServiceNotes;
        },
        addAnotherParty(){
            this.validateForm();
            if(!this.formIsValid){
                return;
            }
            this.$emit('add-parties', this.additionalInfo); //event
            console.log(this.clearForm);
        },
        
        clearForm(){
            this.additionalInfo.fullName = '';
            this.additionalInfo.serviceAddress = '';
            this.additionalInfo.preAuthorize = false;
        }
    }
}
</script>

Parent Component

<template>
    <div>
        <base-card 
        ref="childComponent"
        @add-parties="updateAdditionalInfoList">
            <!-- Wrapper for the `Parties Being Served` component-->
                <template v-slot:title>
                    <slot></slot>
                </template>

        </base-card>
    </div>
    
</template>
<script>
export default {
    data() {
        return {
            hasElement: false,
            selectedComponent: 'base-card',
            additionalInfoList : [],
            clearForm: false
        }
    },
    methods: {
        updateAdditionalInfoList(additionalInfo){ //save changes passed via event
            this.additionalInfoList.push(additionalInfo);
            console.log('emitted');
            console.log(this.additionalInfoList);    
            setTimeout(() => {
                this.$refs.childComponent.clearForm();  //clear the form in child
            }, 2000);
            
        }
    }
}
</script>

Solution

  • Try this

    addAnotherParty(){
      this.validateForm();
      if(!this.formIsValid){
        return;
      }
      let emitObj = JSON.parse(JSON.stringify(this.additionalInfo));
      this.$emit('add-parties', emitObj); //event
      console.log(this.clearForm);
    }
    

    If your object is not deep then you can use

    let emitObj = Object.assign({}, this.additionalInfo);
    

    instead of stringify and parse