murday1983
murday1983

Reputation: 4006

Call method when modal closes in Vue

I have a Vue app (and I'm relatively new to Vue), anyway I have a generic error modal which is displayed when any of my axios calls fail.

On the modal, I want to be able to retry the failed process when the 'Retry' button is clicked but I'm struggling a bit on how to achieve this. I don't think props will help me as the modal is triggered by

VueEvent.$emit('show-error-modal')

I have managed in my catch to pass the function which has failed by using

 VueEvent.$emit('show-error-modal', (this.test));

Then in my modal, I have access to it using

created() {
    VueEvent.$on('show-error-modal', (processFailed) => {
        console.log('processFailed', processFailed)
        this.processFailed = processFailed;
        $('#errorModal').modal('show').on('shown.bs.modal', this.focus);
    });
}

Using 'F12' it gives

test: function test() {
      var _this2 = this;

      var page = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
      alert('boo');
      this.loading = true;
      var order_by = {
        'ho_manufacturers.name': 4,
        'services.servicename': 4
      };

      axios.post('/test/url', {
        id: this.selectedManufacturers,
        page: page,
        order_by: order_by
      }).then(function (response) {
        var paginator = response.data.paginator;

        _this2.$store.dispatch('paginateProducts', paginator);

        _this2.$store.dispatch('setProductPaginator', paginator);

        _this2.loading = false;
      })["catch"](function (error) {
        var processFailed = 'fetchProducts';
        _this2.loading = false;
        VueEvent.$emit('show-error-modal', _this2.test);
        console.log(error);
      });
    },

I don't think this is the right way of doing it though as all this. are replaced with _this2 as shown above. I need the modal to be generic so I can reuse it but I can't figure it out how to retry the process when clicking the button.

The modals are registered in my app.vue file as

<template>
    <div>
        <!-- Other code here -->
        <app-error-modal />
    </div>
</template>
<script>
   // Other code here
   import ErrorModal from './components/ErrorModal';

   export default {
      name: 'App',

      components: {
         // Other code here
        appErrorModal: ErrorModal
      }

     // Other code here
</script>

Modal button HTML

<button ref="retryButton" class="btn btn-success col-lg-2" type="submit" data-dismiss="modal" @click="retryProcess">Retry</button>

Modal script code

<script>
export default {
    name: "ErrorModal",

    created() {
        VueEvent.$on('show-error-modal', (processFailed) => {
            console.log('processFailed', processFailed)
            this.processFailed = processFailed;
            $('#errorModal').modal('show').on('shown.bs.modal', this.focus);
        });
    },

    methods: {
        focus() {
            this.$refs.retryButton.focus();
        },

        retryProcess() {
            //this.$parent.test();   TRIED THIS BUT DIDN'T WORK
        }
    }
}
</script>

I'd rather not have to the store.

Upvotes: 0

Views: 1601

Answers (2)

LMK
LMK

Reputation: 1551

Everything you have there looks correct. You are passing the function to retry ("test") as "processFailed" - I would call that something different such as retryFn.

Then in your error modal component you just need:

<button @click="processFailed">Retry</button>

Don't worry about what the browser shows you in F12, that is the transpiled Javascript, it will work fine.

Upvotes: 0

Adrien Leloir
Adrien Leloir

Reputation: 503

Use custom event on your component

<div id="app">
    <error-modal v-if="isError" v-on:retry-clicked="retry"></error-modal>
    <button @click="isError = true">Make Error</button>
</div>


const errorModal = {
    template : "<button @click=\"$emit('retry-clicked')\">Retry</button>"
}

new Vue({
    el : "#app",
    data : {
        isError : false
    },
    components : {
        errorModal
    },
    methods : {
        retry : function(){
            this.isError = false;
            console.log("child component has called parent when retry clicked")
        }
    }
})

Custom event on component - VUEJS DOC

Upvotes: 1

Related Questions