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

useLarafetch with async functions inside other composable #19

Closed
carlosvaldesweb opened this issue Nov 21, 2023 · 4 comments
Closed

useLarafetch with async functions inside other composable #19

carlosvaldesweb opened this issue Nov 21, 2023 · 4 comments

Comments

@carlosvaldesweb
Copy link

Hello, i'm trying to use "useLarafetch" inside of my composable called "useDocuments", i'm trying to get documents from laravel in lazy mode, to show skeletons while documents loads. The function is called like it doesn't be async function, so i can't use loadingDocuments var because it is always false, any suggestion? Is an error that i can't see in useLarafetch? Maybe is running always in ssr? If i use useLarafetch directly in setup funcion it works, but when i try to use in my composable with lazy option, it works like ssr.

useDocuments.ts

export const useDocuments = () => {
  const documents = useState<Pagination<Document> | null>(
    "documents",
    () => null,
  );

  const document = useState<Document | null | undefined>(
    "document",
    () => null,
  );
  const isEditing = useState<boolean>("isEditing", () => false);
  const loadingDocuments = useState<boolean>("loadingDocuments", () => false);

  const getDocuments = async () => {
    loadingDocuments.value = true;
    try {
      const { data, pending } = await useLarafetch<Pagination<Document>>(
        "/documents",
        {
          lazy: true,
        },
      );
      loadingDocuments.value = false;
      documents.value = data.value;
      return { data, pending };
    } catch (error) {
      console.log(error);
    }
  };

documents.vue

const { getDocument, documents, getDocuments, isEditing, loadingDocuments } =
  useDocuments();
await getDocuments();
@amrnn90
Copy link
Owner

amrnn90 commented Nov 22, 2023

Not really sure what you are trying to do, why not just do this?

// useDocuments.ts
export const useDocuments = async () => {
  const { data: documents, ...rest } = await useLarafetch("/documents", {
    lazy: true,
  });

  return {
    documents,
    ...rest,
  };
};
// documents.vue
<script setup lang="ts">
const {documents, pending} = await useDocuments();
</script>

<template>
  <div>
    <div v-if="pending">Loading...</div>
    <pre v-else>{{ documents }}</pre>
  </div>
</template>

@carlosvaldesweb
Copy link
Author

carlosvaldesweb commented Nov 22, 2023

I want to save the documents and function in composable to use in different components as state. I.e I need to reload documents when user add new document in createDocument.vue component or when edit the title in editDocument component. Also I have a paginated documents. I think to call to getDocuments with the new cursor to push new documents in infinite scroll

@amrnn90
Copy link
Owner

amrnn90 commented Nov 22, 2023

In this case I would suggest using pinia and calling $larafetch directly, maybe something like this:

// useDocuments.ts

import { defineStore } from "pinia";

export const useDocuments = defineStore("documents", () => {
  const documents = ref<undefined | null | any[]>(undefined);
  let page = ref(1);
  const pending = ref(false);

  async function getDocuments() {
    pending.value = true;
    documents.value = documents.value ?? null;
    const newDocs = await $larafetch(`/documents?page=${page.value}`);
    pending.value = false;
    documents.value = [...(documents.value || []), ...newDocs];
  }

  async function nextPage() {
    page.value++;
    return getDocuments();
  }

  return {
    documents,
    page,
    nextPage,
    pending,
  };
});
// documents.vue
<script setup lang="ts">
const docStore = useDocuments();
if (docStore.documents === undefined) {
   await docStore.nextPage();
}
</script>

<template>
  <div>
    <pre v-if="docStore.documents">{{ docStore.documents }}</pre>
    <div v-if="docStore.pending">Loading...</div>
    <button @click="() => docStore.nextPage()">Get</button>
  </div>
</template>

Hope this helps you out,
I am closing this since it is not directly related to this repo.

@amrnn90 amrnn90 closed this as completed Nov 22, 2023
@amrnn90
Copy link
Owner

amrnn90 commented Nov 22, 2023

BTW if you are looking for a full-featured solution to this kind of problem then you might want to consider using TanStack Query, they have an example of making it work with Nuxt.

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

No branches or pull requests

2 participants