What is the best way to sort inertia data on the client-side?

Looking for a solution with my component that receives data, I have the following setup in my controller:

route::get('/', function() { return inertia('foo', ['data' => Model::all()]) });

Within my Vue component:

<template>
   <ul> 
      <li v-for="item in data">{{item.name}}</li>
   </ul>
</template>
<script setup>
defineProps({ data: Object })
</script>

My objective is to display the data based on either name or score depending on a checkbox value. Rather than making a server-side request, I'm exploring options to handle this within the component itself.

However, it seems that props are read-only, preventing me from implementing something like this:

 <li v-for="Object(data).sort((a, b) => b.score - a.score)">

Do you have any other suggestions?

The type of props.data is as follows:

Proxy {0: {…}, 1: {…}, 2: {…}, 3: {…}, 4: {…}, 5: {…}, 6: {…}, 7: {…}, 8: {…}, 9: {…}, 10: {…}, 11: {…}, 12: {…}, 13: {…}, 14: {…}, 15: {…}, 16: {…}}
[[Handler]]: Object
[[Target]]: Object
0: {id: 1, user: null, name: 'foobar', score: 0, …}
1: {id: 2, user: null, name: 'baz', score: 10, …}

And it appears that Object(props.data) does not support a sort method.

Answer №1

<script setup>
import { ref, computed } from "vue";
const props = defineProps({ data: Object });
const sortByScore = ref(true);
const sortBy = computed(() => (sortByScore.value ? "score" : "name"));
const sortedData = computed(() =>
  Object.values(props.data).sort((a, b) => b[sortBy.value] - a[sortBy.value])
);
</script>

Connect the checkbox to sortByScore.


I prefer using reactive() instead of dealing with

.value</code in my controllers:</p>
<pre><code>import { reactive, computed, toRefs } from "vue";
const props = defineProps({ data: Object });
const state = reactive({
  sortByScore: true,
  sortBy: computed(() => (state.sortByScore ? "score" : "name")),
  sortedData: computed(() =>
    Object.values(props.data).sort((a, b) => b[state.sortBy] - a[state.sortBy])
  ),
});

// expose state for easier access in the template
const { sortByScore, sortBy, sortedData } = toRefs(state);

I find this syntax cleaner and more efficient, especially for larger controllers.
It also allows for easy typing of the state using just one interface.

Some developers like to assign state as S and directly use it in the template without unwrapping it.


Note: Transforming the data from Object to Array is necessary to maintain the element order reliably. Objects cannot be sorted consistently in JavaScript.

Answer №2

Experience the power of using computed properties

<script setup>
import { computed } from 'vue'
const props = defineProps({ data: Object })

const sortedData = computed(() => Object(props.data.value).sort((a, b) => b.score - a.score))
</script>

Remember to include a :key attribute utilizing a UUID in your v-for loop for optimized Vue.js performance!

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Struggling to reflect changes in the database using the updated value in the localStorage

I have a table where the td is set to contenteditable. To update the value of the td in my database, I decided to use localStorage. When the save button is clicked, the inputted value in the td will be saved to localStorage and retrieved via AJAX to replac ...

Monitor fetch() API calls and responses in JavaScript

I’m looking to intercept fetch API requests and responses using JavaScript. Specifically, I want to be able to capture the request URL before it is sent and also intercept the response once it has been received. The code below demonstrates how to inter ...

Issue with angularjs ui.router delaying the rendering of ui-view

I've been working on implementing ui-router in my project. Here is the core module setup: var core = angular.module('muhamo.core', ['angular-loading-bar', 'anguFixedHeaderTable', 'ui.router']); For the tra ...

What are some alternatives to using multiple slot transclution in an Angular 1.5 component?

In the process of constructing a panel component using angular 1.5, I am looking to embed some markup into this template (which has been simplified): <div class="panel"> <h1>{{ $ctrl.title }}</h1> <div ng-transclu ...

Is it possible to use both material-ui@next and the previous version concurrently?

I need some advice on a project I am working on that utilizes material-ui@next (v1). While I appreciate the new features in the latest autocomplete, I find it too complex for my needs. Instead, I would like to revert back to the older version of the autoco ...

React fails to acknowledge union types

I have the following types defined: export enum LayersItemOptionsEnum { OPERATOR, HEADER, } type sharedTypes = { children: string | ReactElement; }; type LayersItemStatic = sharedTypes & { label: string; option: LayersItemOptionsEnum; }; t ...

VueJS dynamic AppBar based on certain conditions

When using Vuetify, what is the most efficient method for managing differently styled appbars on different pages? Additionally, how can the back button be activated instead of the hamburger icon through programming? For instance, if there are 5 screens a ...

Discord bot that combines the power of discord.js and node.js to enhance your music

I am currently working on a Discord bot designed to play music in voice chat rooms. However, I am facing some issues with properties. Whenever I try to launch the bot using "node main", I encounter the following error message: "TypeError: Cannot read prope ...

Exploring the functionalities of the useState object with mapping techniques

While attempting to convert my class-based component to a functional style, I encountered the following code: const [foo, setFoo] = useState(null); const [roomList, setRoomList] = useState([]); useEffect(() => { setRoomList(props.onFetchRooms(props.to ...

TS1057: It is required that an async function or method has a return type that can be awaited

There was a recent Github issue reported on March 28th regarding async arrow functions generating faulty code when targeting ES5, resulting in the error message: TS1057: An async function or method must have a valid awaitable return type You can find t ...

Tips for Using VueComponent with the $vuetify.goTo() Function

I have three view components named home, about, and work in the App.vue file. <v-app> <ToolBar /> <v-content> <router-view name="home"></router-view> <router-view name="about"></router-view> ...

Navigating Through Grid and Card Content in React

My goal was to minimize the amount of code by incorporating a reusable component into my application. I am facing an issue on how to iterate through the columns and rows in Grid, Card, and Table. What would be the optimal solution for this problem? Please ...

Is it possible to dynamically assign and call functions through an Object in Angular 6?

I implemented a click handler for a button that is generated dynamically. Within the click handler function, I am invoking a callback function. However, I encountered an issue where an error message popped up stating that "Callback function is not a fu ...

Ensure that both the top row and leftmost column are fixed in a vertical header using JQuery DataTable

Check out the implementation of vertical header flow in Datatables by visiting: https://jsfiddle.net/2unr54zc/ While I have successfully fixed the columns on horizontal scroll, I'm facing difficulty in fixing the first two rows when vertically scroll ...

Exploring Heroes in Angular 2: Retrieving Object Information by Clicking on <li> Items

Currently, I am delving into the documentation for an angular 4 project called "Tour of Heroes" which can be found at https://angular.io/docs/ts/latest/tutorial/toh-pt2.html. <li *ngFor="let hero of heroes" (click)="onSelect(hero)">{{hero.name}}< ...

exit out of React Dialog using a button

I have a scenario where I want to automatically open a dialog when the screen is visited, so I set the default state to true. To close the dialog, I created a custom button that, when clicked, should change the state to false. However, the dialog does no ...

Is there a way to locate a parent class starting from a child class, and subsequently track down another child class from the parent?

I am facing a challenge with multiple tags structured like this: <div class="A"> <div class="B1">...</div> <div class="C1">Hello World!</div> <div class="C2">World Hell ...

Attaching the JSON data to ngModel in Angular 2

I have received a json response containing various fields, including the rewards.rewardName value. I'm trying to figure out how to bind this specific value to [(ngModel)] in Angular 2. [ { "id": 18, "gname": "learning ramayanam", "goalCat ...

Align the text field value with the corresponding tooltip content in Vuetify

<v-col class="d-flex align-center"> <v-tooltip bottom> <template v-slot:activator="{ on }"> <v-text-field v-on="on" :value="info.payeeNo" den ...

The ng-repeat directive adds an additional line after each iteration of the list item

Whenever the angular directive ng-repeat is utilized with an <li> element, I notice an additional line appearing after each <li>. To demonstrate this issue, see the simple example below along with corresponding images. Here is a basic example ...