javascript - How can I loop through API resource data but exclude certain properties based on the key when displaying on the fro

I'm working on creating a table component using Vuejs. The app uses laravel as the backend along w

I'm working on creating a table component using Vuejs. The app uses laravel as the backend along with inertiajs. I have a resource that is returned for displaying a resource. In the resource I am trying to add some data that I don't want displayed, these will be links to edit and delete the resource. I also may have to add an ID for having a checkbox on each row of the table as well.

My question is how can I exclude the links and meta from being displayed in the loop of data but then show them as a checkbox or link? It's been a long day I hope this is clear.

PermissionResource

public function toArray($request)
{
    return [
        'name' => $this->name,
        'links' => [
            'edit' => action([PermissionController::class, 'edit'], $this),
            'delete' => action([PermissionController::class, 'destroy'], $this),
        ],
        'meta' => [
            'id' => $this->id
        ]
    ];
}

Table.vue

<script setup>
import { computed, ref } from 'vue';

const props = defineProps({
    data: {
        type: Object,
        required: true
    }
});

const hasActionLinks = ref(props.data.filter((item) => item.hasOwnProperty('links')));
const hasRowSelector = ref(props.data.filter((item) => item.hasOwnProperty('meta')));

</script>

<template>
    <div>
        <table>
            <thead>
                <tr>
                    <th v-if="hasRowSelector" scope="col">
                        <input id="selectAll" type="checkbox" v-model="selectAll" />
                    </th>

                    <th v-for="(heading, index) in Object.keys(data[0]).map((heading) => heading.replace(/_/g, ' '))" v-bind:key="index" scope="col">
                        {{ heading }}
                    </th>

                    <th v-if="hasActionLinks" scope="col">
                        Actions
                    </th>
                </tr>
            </thead>

            <tbody>
                <tr v-for="(row, index) in Object.values(data)" :key="index">

                    <td v-if="hasRowSelector">
                        <input type="checkbox" v-model="selected" :value="row.meta.id" />
                    </td>

                    <td v-for="(value, myindex) in Object.values(row)" v-bind:key="myindex">
            {{ value }}
                    </td>

                    <td v-if="hasActionLinks">
                        // EDIT AND DELETE LINKS HERE
                    </td>
                </tr>
            </tbody>
        </table>
    </div>
</template>

This is the current result

I'm working on creating a table component using Vuejs. The app uses laravel as the backend along with inertiajs. I have a resource that is returned for displaying a resource. In the resource I am trying to add some data that I don't want displayed, these will be links to edit and delete the resource. I also may have to add an ID for having a checkbox on each row of the table as well.

My question is how can I exclude the links and meta from being displayed in the loop of data but then show them as a checkbox or link? It's been a long day I hope this is clear.

PermissionResource

public function toArray($request)
{
    return [
        'name' => $this->name,
        'links' => [
            'edit' => action([PermissionController::class, 'edit'], $this),
            'delete' => action([PermissionController::class, 'destroy'], $this),
        ],
        'meta' => [
            'id' => $this->id
        ]
    ];
}

Table.vue

<script setup>
import { computed, ref } from 'vue';

const props = defineProps({
    data: {
        type: Object,
        required: true
    }
});

const hasActionLinks = ref(props.data.filter((item) => item.hasOwnProperty('links')));
const hasRowSelector = ref(props.data.filter((item) => item.hasOwnProperty('meta')));

</script>

<template>
    <div>
        <table>
            <thead>
                <tr>
                    <th v-if="hasRowSelector" scope="col">
                        <input id="selectAll" type="checkbox" v-model="selectAll" />
                    </th>

                    <th v-for="(heading, index) in Object.keys(data[0]).map((heading) => heading.replace(/_/g, ' '))" v-bind:key="index" scope="col">
                        {{ heading }}
                    </th>

                    <th v-if="hasActionLinks" scope="col">
                        Actions
                    </th>
                </tr>
            </thead>

            <tbody>
                <tr v-for="(row, index) in Object.values(data)" :key="index">

                    <td v-if="hasRowSelector">
                        <input type="checkbox" v-model="selected" :value="row.meta.id" />
                    </td>

                    <td v-for="(value, myindex) in Object.values(row)" v-bind:key="myindex">
            {{ value }}
                    </td>

                    <td v-if="hasActionLinks">
                        // EDIT AND DELETE LINKS HERE
                    </td>
                </tr>
            </tbody>
        </table>
    </div>
</template>

This is the current result

Share Improve this question asked Mar 12 at 16:45 Danny ConnollyDanny Connolly 9013 gold badges10 silver badges31 bronze badges 2
  • It makes more sense to prepare data you iterate to fit presentation better instead of writing js in a template. For dynamic reactive data use computeds – Estus Flask Commented Mar 12 at 18:41
  • @EstusFlask Thanks for your comment. So would you suggest having the resource return a showable key along with links and meta and then put the columns I want to show in the showable array? – Danny Connolly Commented Mar 12 at 21:30
Add a comment  | 

1 Answer 1

Reset to default 0

You could change your v-for="(value, myindex) in Object.values(row)" to ignore the property "links" and "meta". This could be done using either a function, or a computed value.

<script>
const unwantedColumns = ref(['links', 'meta']);

const getFilterableProps = (row) => {
  return Object.values(row).filter(col => !unwantedColumns.value.includes(col));
}
</script>

And then use this function in your template

            <tbody>
                <tr v-for="(row, index) in Object.values(data)" :key="index">

                    <! -- ... -->

                    <td v-for="(value, myindex) in getFilterableProps(row)" v-bind:key="myindex">
                        <! -- ... -->
                    </td>

                     <! -- ... -->
                </tr>
            </tbody>

A more efficient way to do this would be to declare a "columns" array that contains all the columns you want to show and iterate through that, rather than attempting to dynamically defines the columns.

<script>
const columns = ref([
  'property1',
  'property2',
  ...
])
</script>

<template>
  <!-- ... -->
   <td v-for="(column, myindex) in columns" v-bind:key="myindex">
            {{ row[column] }}
   </td>
   <!-- ... -->
</template>

Anyways, I hope this gave you some ideas on how to fix the issue. Please note that the provided code is UNTESTED and should be used as reference only.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744739302a4590933.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信