0

I am new to JS and Vue, so please bear with me :)

I have a table that is rendered using two Vue components which are a parent (the table - orders) and child (the row - order).

There is a button that can be pressed on each row of the table that carries out an AJAX against that row, but I also need to have the table (parent) refresh when the action is carried out so it has the updated data.

I think I need to use $emit in the child to pass the action on to the parent, but I can't get it to work. Here is the code (sorry its long, I removed everything non-essential);

const order = {
    template: `
        ...// table content
        <td><button class="btn btn-default btn-sm" @click="assignAdvisor(id, 
                                       selectedOption)">Set Advisor</button></td>
    `,

    methods: {
        // following is the method that is run when the button is pressed

        assignAdvisor(id, selectedOption) {
            axios.post('url').then(response => {
                ..// show response message
                orders.$emit('refreshAfterUpdate'); // also tried  
                                                   // this.$parent.$emit(...)
            })      
    },   
};

const orders = {
    components: { order, },

    props: {
        orders: {
            type: Object,
        },
    },

    mounted() {
        // this is basically the code that I need to re-run when button is pressed,  
        // which I have repeated below in a method
        var refresh = () => {
            axios.get('/admin/ajax/unassigned-orders')
                .then(response => {
                this.ordersData = response.data;
                setTimeout(refresh, 5000);
            });
        }
        refresh();
    },

    methods: {
        refreshAfterUpdate() {
            axios.get('/admin/ajax/unassigned-orders')
            .then(response => {
            this.ordersData = response.data;
            console.log(response);
            });
        },
    }
};

new Vue({
    render(createElement) {
        const props = {
            orders: {
                type: Object,
            },
        };
        return createElement(orders, { props });
    },
}).$mount('#unassignedOrders');

I don't get any error message or anything - it just doesn't work.

Thanks

the_peacock
  • 399
  • 2
  • 5
  • 19
  • I don't see any code that captures the event with the [`$on method`](https://vuejs.org/v2/api/#vm-on). – PatrickSteele Feb 17 '17 at 18:17
  • @PatrickSteele ah that sounds like it could be the problem. I thought emit would run the refreshAfterUpdate method in the parent? – the_peacock Feb 17 '17 at 18:22
  • No, `$emit` takes an "eventName" and, optionally, additional arguments. Your `$on` handler for the "eventName" can call the refresh. – PatrickSteele Feb 17 '17 at 18:26

1 Answers1

1

OK so thanks to @Patrick Steele I have figured it out.

I was not using $on - oops.

Added code to the mounted() section and it now works:

const order = {
    template: `
        ...// table content
        <td><button class="btn btn-default btn-sm" @click="assignAdvisor(id, 
                                       selectedOption)">Set Advisor</button></td>
    `,

    methods: {
        // following is the method that is run when the button is pressed

        assignAdvisor(id, selectedOption) {
            axios.post('url').then(response => {
                ..// show response message
                orders.$emit('refreshAfterUpdate'); // also tried  
                                                   // this.$parent.$emit(...)
            })      
    },   
};

const orders = {
    components: { order, },

    props: {
        orders: {
            type: Object,
        },
    },

    mounted() {
        // this is basically the code that I need to re-run when button is pressed,  
        // which I have repeated below in a method
        var refresh = () => {
            axios.get('/admin/ajax/unassigned-orders')
                .then(response => {
                this.ordersData = response.data;
                setTimeout(refresh, 5000);
            });
        }
        refresh();

            $this.on('refreshAfterUpdate', () => {
                axios.get('/admin/ajax/unassigned-orders')
                .then(response => {
                this.ordersData = response.data;
                console.log(response);
                });
            },
        },
    },


};

new Vue({
    render(createElement) {
        const props = {
            orders: {
                type: Object,
            },
        };
        return createElement(orders, { props });
    },
}).$mount('#unassignedOrders');
the_peacock
  • 399
  • 2
  • 5
  • 19
  • Also, I just noticed that I needed to use this.$parent.$emit instead of orders.$emit to get it to recognise the parents function... – the_peacock May 09 '17 at 20:45