Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[UTable] Why Reactive sorting does not auto-refetch data? #1085

Closed
ddahan opened this issue Dec 11, 2023 · 2 comments
Closed

[UTable] Why Reactive sorting does not auto-refetch data? #1085

ddahan opened this issue Dec 11, 2023 · 2 comments
Labels
question Further information is requested

Comments

@ddahan
Copy link

ddahan commented Dec 11, 2023

Description

Hi there!
I'm trying to build a table that requires back-end data for both pagination and sorting.

It works perfectly for pagination: when endpoint value is updated, thanks to the watch property, the data is automatically re-fetched and updated.

But I don't understand why for sorting, it does not work. here is my current code:

<template>
  <UTable :rows="data?.items" :columns="columns" v-model:sort="sort" />
    <template v-if="data">
      <UButton
        :disabled="!data.previous_page"
        icon="i-ph-arrow-circle-left-bold"
        @click="endpoint = data.previous_page"
      />
      <div class="">Page {{ data.page }}</div>
      <UButton
        :disabled="!data.next_page"
        icon="i-ph-arrow-circle-right-bold"
        @click="endpoint = data.next_page"
      />
    </template>
</template>
<script setup lang="ts">
const sort = ref({
  column: "identifier",
  direction: "desc" as "asc" | "desc",
});

// Translates Nuxt convention to Django one
let djangoDirection = computed(() => (sort.value.direction === "desc" ? "-" : ""));

let endpoint: Ref<any> = ref(
  `/badges?order_by=${djangoDirection.value}${sort.value.column}`
);

const { data, status, error } = await useFetch<Paginated<BadgeSchema>>(endpoint, {
  method: "get",
  watch: [endpoint], // auto-refresh when endpoint is changed
  baseURL: `${backHostUrl}/${apiBase}`,
  timeout: 5000,
});

Thanks for your help.

@ddahan ddahan added the question Further information is requested label Dec 11, 2023
Copy link
Member

benjamincanac commented Dec 11, 2023

I think this is a duplicate of #946.

@ddahan
Copy link
Author

ddahan commented Dec 11, 2023

I think I messed up with reactivity initially. Here is a complete working version with a slightly different logic.
Maybe it could help someone by seing a complete example with a real backend interaction.

Assuming my response data are typed like this when using pagination:

interface Paginated<T> {
  nb_items: number;
  nb_pages: number;
  page: number;
  items: T[];
}

Here is a working example with both pagination and table sorting:

<template>
  <h2 class="text-4xl font-semibold">Badges</h2>
  <template v-if="data">
    <div class="mt-6 flex flex-col gap-y-2">
      <UTable
        v-model:sort="sort"
        @update:sort="page = 1"
        :loading="pending"
        :columns="columns"
        :rows="data.items"
      />
    </div>
    <div class="mt-6 flex gap-x-4 items-center justify-center">
       <UPagination v-model="page" :total="data.nb_items" />
    </div>
  </template>
</template>
<script setup lang="ts">
const sort = ref({
  column: "identifier",
  direction: "desc" as "asc" | "desc",
});

let page = ref(1);

// Translates Nuxt UI ordering convention to Django one
let djangoDirection = computed(() => (sort.value.direction === "desc" ? "-" : ""));

let endpoint = computed(
  () => `badges?page=${page.value}&order_by=${djangoDirection.value}${sort.value.column}`
);

const { data, status, pending, error } = await useFetch<Paginated<BadgeSchema>>(
  endpoint,
  {
    method: "get",
    watch: [endpoint], // auto-refresh when endpoint is changed
    baseURL: `${backHostUrl}/${apiBase}`,
    timeout: 5000,
  }
);

if (status.value === "error") {
  handleError(error);
}

const columns = [
  {
    key: "identifier",
    label: "ID",
    sortable: true,
  },
  {
    key: "expiration",
    label: "Expiration",
    sortable: true,
  },
  {
    key: "owner_name",
    label: "Owner",
  },

  {
    key: "is_active",
    label: "Is active ?",
  },
];
</script>

EDIT: use built-in UPagination component (which is excellent 👏🏻 by the way)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants