0

I've been stuck on this issue for a few weeks now think time to ask for help.

Basically I am using Laravel with Vue 2 and the matfish2/vue-tables-2 package and all is well the table displays no issues there. The thing is when I do an action such as delete a row and after I axios to remove from database I want to trigger the refresh() to redraw the table. The docs suggest running this:

 this.$refs.myTable.refresh()

If I add a button @click to trigger my function to call this it works fine but if I try to call this after my axios response the method seems to not have access to the $refs for that $refs table at all.

I was reading this in attempts to shed some light:

https://forum.vuejs.org/t/accessing-refs/15049/12

This works if I'm trying to access it during the lifecycle till it gets destroyed but doesn't help me when the page is already rendered.

Here is my file setup:

app.js

// main vue
import Vue from 'vue'

// axios
import axios from 'axios'
window.axios = require('axios');

window.axios.defaults.headers.common = {
    'X-CSRF-TOKEN': window.Laravel.csrfToken,
    'X-Requested-With': 'XMLHttpRequest'
};

// datatables
import {ServerTable, ClientTable, Event} from 'vue-tables-2'
Vue.use(ServerTable, {}, false);
Vue.use(ClientTable, {}, false);

// vue2-simpalert-plugin
import Simplert from 'vue2-simplert-plugin'
Vue.use(Simplert)

//compoonents
import Modal from './components/modals/show-modal.vue'
import DimChart from './components/dimfactor/dimchart.vue'
import OOSManager from './components/oosmanager/oosmanager.vue'
import DailyShipments from './components/dailyshipments/dailyshipments.vue'

if (document.getElementById("app")) {
    var app = new Vue({
        el: '#app',

        components: {
            'modal': Modal,
            'dimchart': DimChart,
            'oosmanager': OOSManager,
            'dailyshipments': DailyShipments
        },

        methods: {

        }

    });

    window.vue = app;
}

oosmanager.vue

<template>
    <div id="oosmanager" class="container-fluid">
        <button type="button" class="btn btn-primary">Add New OOS</button>
        <button type="button" class="btn btn-primary" @click="refresh">Refresh</button>
        <div class="row">
            <div class="col-sm-12">
                <v-server-table url="oosmanager/getData" :columns="columns" :options="options" ref="myOOSTable">
                    <template slot="qty" scope="props">
                        {{ props.row.get_item.qty }}
                    </template>

                    <template slot="customers" scope="props">
                        <div class="container-fluid">
                            <p><button type="button" class="btn btn-primary">Add</button></p>
                            {{ props.row }}
                            <div v-if="typeof props.row.get_customer_items.length !== 'undefined'">
                                <div v-if="props.row.get_customer_items.length > 0">
                                    <table class="table table-bordered customers__table">
                                        <thead>
                                            <tr>
                                                <th class="customers__name">Name</th>
                                                <th class="customers__notes">Notes</th>
                                                <th class="customers__editrep">Rep</th>
                                                <th class="customers__buttons"></th>
                                            </tr>
                                        </thead>
                                        <tbody>
                                            <tr v-for="items in props.row.get_customer_items">
                                                <td>{{ items.get_customer.customerName }}</td>
                                                <td>{{ items.notes }}</td>
                                                <td>{{ items.lastEditRep }}</td>
                                                <td><button type="button" class="btn btn-danger" @click="open('deleteCustomerRow', items)">&nbsp;x&nbsp;</button></td>
                                            </tr>
                                        </tbody>
                                    </table>
                                </div>
                            </div>
                        </div>
                    </template>

                    <template slot="delete" scope="props">
                        <button type="button" class="btn btn-danger" @click="open('deleteRow', props.row)">&nbsp;x&nbsp;</button>
                    </template>
                </v-server-table>
            </div>
        </div>
    </div>
</template>

<script>
    export default {
        props: [],
        data() {
            return {
                columns: [
                    'created_at',
                    'sku',
                    'qty',
                    'customers',
                    'delete',
                ],
                options: {
                    headings: {
                        created_at: 'Date / Time',
                        delete: '',
                    },
                    columnsClasses: {
                        'created_at': 'created-at',
                        'sku': 'sku',
                        'qty': 'qty',
                        'customers': 'customers',
                        'delete': 'delete'
                    },
                    sortable: [
                        'created_at',
                        'sku',
                        'qty'
                    ]
                }
            }
        },

        methods: {
            open (area, row) {
                if (area == 'deleteRow') {
                    let confirmFn = function() {
                        axios.get('oosmanager/test/'+row.id).then(function(response) {
                            this.refresh;
                        });
                    }

                    let obj = {
                        title: 'Delete ' + row.sku + '?' ,
                        message: 'Are you sure?',
                        type: 'info',
                        showXclose: true,
                        useConfirmBtn: true,
                        onConfirm: confirmFn
                    }               
                    this.$Simplert.open(obj);
                }

                if (area == 'deleteCustomerRow') {
                    let confirmFn = function() {
                        console.log(customersItemsId = row.id);
                        console.log(this.refresh);
                    }

                    let obj = {
                        title: 'Delete ' + row.get_customer.customerName + '?' ,
                        message: 'Are you sure?',
                        type: 'info',
                        showXclose: true,
                        useConfirmBtn: true,
                        onConfirm: confirmFn
                    }               
                    this.$Simplert.open(obj);
                }
            },

            refresh() {
                this.$refs.myOOSTable.refresh();
            }
        },

        mounted() {

        }
    }
</script>

<style lang="css">
    #oosmanager {
        width: 100%;
    }

    #oosmanager th {
        text-transform: uppercase;
    }

    #oosmanager th.created-at {
        width: 8%;
    }

    #oosmanager th.sku {
        width: 23%;
    }

    #oosmanager th.customers {
        width: 63%;
    }

    #oosmanager th.qty {
        width: 4%;
    }

    #oosmanager th.delete {
        width: 2%;
    }

    #oosmanager td.delete {
        vertical-align: middle;
    }

    #oosmanager th.delete span {
        text-align: center;
    }


    #oosmanager .customers__table {
        width: 100%;
        table-layout: fixed;
    }

    #oosmanager .customers__table .customers__name {
        width: 22%;
    }

    #oosmanager .customers__table .customers__notes {
        width: 59%;
    }

    #oosmanager .customers__table .customers__editrep {
        width: 15%;
    }

    #oosmanager .customers__table .customers__buttons {
        width: 4%;
    }

    .VueTables__child-row-toggler {
    width:16px;
    height:16px;
    line-height: 16px;
    display: block;
    margin: auto;
    text-align: center;
    }

    .VueTables__child-row-toggler--closed::before {
    content: "+";
    }

    .VueTables__child-row-toggler--open::before  {
    content: "-";
    }   
</style>

index.blade.php

@extends('defaults.skeleton')
@section('title')
    <div class="container-fluid">
        <div id="page-title" class="row">
            <p><h2>OOS Manager</h2></p>
        </div>
    </div>
@stop
@section('content')
    <meta name="csrf-token" content="{{ csrf_token() }}">
    <div id="app">
        <simplert></simplert>
        <oosmanager></oosmanager>
    </div>
@stop

Recap

So basically a button to trigger the method will see the $refs and refresh/redraw correctly but if trying to access $refs inside my method after the axios call it won't see it in the dom at all and shows undefined. Tried putting in mounted but didn't help since that seems to be related to last part of rendering. How do I access it correctly?

Update

I wasn't able to access it fully in my axios response but it is now showing up in my created() or mounted() this way so that was helpful insight from the duplicate post. However I did make it happen by declaring it into a global var such as this:

created() {
    var self = this;
    window.myData = this.$refs;
}

and then my axios response:

axios.get('oosmanager/test/'+row.id).then(function(response) {
    window.myData.myOOSTable.refresh();
});

Not sure if correct approach but it's working at this moment.

Matanya
  • 6,233
  • 9
  • 47
  • 80
dmotors
  • 611
  • 2
  • 7
  • 19
  • @Bert Thanks didn't find that post during my searches. I can now see it during created or mounted but still not sure how to access it inside my callback still shows undefined. I ended up using var self = this and window.myData = this.$refs inside my created() and then in my axios response I did window.myData.myOOSTable.refresh() and it worked. I'm not sure if this is the correct approach to put it into a global var but it's the only way I found so far to make it happen. Please shed some light if otherwise. – dmotors Oct 25 '17 at 17:43
  • `axios.get('oosmanager/test/'+row.id).then(() => this.refresh())`. Using an arrow function here will mean that `this` will refer to the Vue in the `refresh` method. – Bert Oct 25 '17 at 18:44
  • @Bert Tried the arrow function but didn't work unfortunately back to the undefined and I console.log(this) and no $refs and no myOOSTable still. – dmotors Oct 25 '17 at 19:41
  • No idea what you are doing at this point. Here is an example. https://codepen.io/Kradek/pen/VMoboE – Bert Oct 25 '17 at 19:50
  • @Bert So your example worked and shed some more light to the issue I was having. Pretty much the axios arrow syntax was fine but the function it was within wasn't using arrow function. Once I changed that now I see everything and using this.$refs business as usual. – dmotors Oct 26 '17 at 02:35

0 Answers0