Axios request giving getter setter methods instead

2019-02-26 21:16发布

问题:

I'm working with Laravel and Vue to make a single page web application. I've used Vue before to get the data from a database using a controller with no problem, but for some reason I'm now only getting a seemingly infinitely nested JS object that has getter and setter methods stored in each parent object instead of the data I queried. I've seen other people with similar issues, but the solutions that worked for them didn't work for me. For example, some people used JSON.parse(JSON.stringify(response.data)); to get just the raw data, but this doesn't work when I attempt to store it in this.actions. Here is my index method in my ActionLogController

public function index($url)
{

    $companyName = explode("/", $url);

    if(Auth::check())
    {
        $company = Company::where('name', '=', strtolower($companyName[count($companyName) - 1]))->first();

        // If sortby not empty
        $sortby = "created_at";

        //assume desc (most recent)
        $sortdirection = 'desc';

        if(request()->has('sortdirection') && request()->sortdirection == 'asc')
        {
            $sortdirection = 'asc';
        }

        // if sortby is set
        if(request()->has('sortby')) 
        {
            $sortby = request()->sortby;

            switch($sortby) 
            {
                case "date":
                    $sortby = "string_date";
                break;
                case "company":
                    $sortby = "company_name";
                break;
                case "name":
                    // do nothing
                break;
                case "communication-type":
                    $sortby = "communication_type";
                break;
                case "contact":
                    // do nothing
                break;
                case "subject":
                    $sortby = "status";
                break;
                case "assigned-to":
                    $sortby = "assigned_to";
                break;
                case "action":
                    $sortby = "action_item";
                break;
                case "assigned-to":
                    $sortby = "assigned_to";
                break;
                default:
                    $sortby = 'created_at';
                break;
            }
        }
    }

    if($sortdirection == 'asc') {
        return Auth::user()->actionLogs
            ->where('activity_key', '=', '1,' . $company->id)
            ->sortBy($sortby);
    }

    return Auth::user()->actionLogs
        ->where('activity_key', '=', '1,' . $company->id)
        ->sortByDesc($sortby);

}

This is my Vue component to get the data from the controller. I know the template code works, because it worked fine when I sent it dummy data before pulling the data from the controller.

<style scoped>
.action-link {
    cursor: pointer;
}

.m-b-none {
    margin-bottom: 0;
}
</style>

<template>
<div class="table-responsive">
    <table class="table table-striped table-sm">
        <thead>
            <tr>
                <th><a id="sortby-date" class="action-nav" href="?sortby=date&sortdirection=desc">Date</a></th>
                <th><a id="sortby-company" class="action-nav" href="?sortby=company&sortdirection=desc">Company</a></th>
                <th><a id="sortby-name" class="action-nav" href="?sortby=name&sortdirection=desc">Name</a></th>
                <th><a id="sortby-communication-type" class="action-nav" href="?sortby=communication-type&sortdirection=desc">Communication Type</a></th>
                <th><a id="sortby-contact" class="action-nav" href="?sortby=contact&sortdirection=desc">Contact</a></th>
                <th><a id="sortby-subject" class="action-nav" href="?sortby=subject&sortdirection=desc">Subject</a></th>
                <th><a id="sortby-action" class="action-nav" href="?sortby=action&sortdirection=desc">Comment/Action Item</a></th>
                <th>Archive</th>
                <!-- check if admin?? -->
                    <th><a id="sortby-assigned-to" class="action-nav" href="?sortby=date&sortdirection=desc">Assigned To</a></th>
                <!-- /check if admin?? -->
            </tr>
        </thead>
        <tbody v-if="actions.length > 0">
            <tr v-for="action in actions">
                <td>
                    {{ action.string_date }}
                </td>
                <td>
                    {{ action.company_name }}
                </td>
                <td>
                    {{ action.name }}
                </td>
                <td>
                    {{ action.communication_type }}
                </td>
                <td>
                    {{ action.contact }}
                </td>
                <td>
                    {{ action.status }}
                </td>
                <td>
                    {{ action.action_item }}
                </td>
                <td>
                    <input type="checkbox" :id="'archive-' + action.id" class="archive" :name="'archive-' + action.id">
                </td>
                <td :id="'record-' + action.id" class="assigned-to">
                    {{ action.assigned_to }}
                </td>
            </tr>
        </tbody>
    </table>
    <p id="add-action" style="text-align: center;">
      <button id="action-log-add" class="btn btn-sm btn-primary edit">Add Item</button>
      <button id="action-log-edit" class="btn btn-sm btn-danger edit">Edit Items</button>
    </p>
</div>
</template>

<script>
export default {
    data() {
        return {
            actions: []
        }
    },
    methods: {
        getActionLogs(location) {

            var company = location.split("/");
            company = company[company.length - 1];

            axios.get('/action-log/' + company)
                 .then(response => {

                    this.actions = response.data;                        
                    console.log(this.actions);

                 })
                 .catch(error => {
                    console.log('error! ' + error);
                 });
        }
    },
    mounted() {
        this.getActionLogs(window.location.href);
    }
}
</script>

This is the output I get in the browser console

    {…}
​
    1: Getter & Setter
​
    2: Getter & Setter
​
    3: Getter & Setter
​
    4: Getter & Setter
​
    5: Getter & Setter
​
    6: Getter & Setter
​
    7: Getter & Setter
​
    8: Getter & Setter
​
    9: Getter & Setter
​
    10: Getter & Setter
​
    __ob__: Object { value: {…}, dep: {…}, vmCount: 0 }
​
    <prototype>: Object { … }

I was expecting to see the normal array of data that gets returned, but this is what shows up instead and then won't update the component with the data. I'm new to Vue, so maybe there's something really easy I missing, but I can't seem to figure this out.

回答1:

Writing up my comments above as a sort of canonical answer to this as it keeps coming up...

What you're looking at is how Vue proxies your data to make it reactive. This is because you're using console.log() on a Vue instance data property.

When you assign values to a data property, it is transformed to an observable so Vue can treat it reactively. I suggest you forget about trying to console.log() anything assigned to this and use the Vue Devtools browser extension to inspect your components and their data if you're having trouble rendering the response.

Please note, there is nothing wrong here.