NuxtN
Nuxt9mo ago
9 replies
Matt

Data Fetching Composable Advice

We have an Organization entity in our app, and each organization has related Events. We’re expecting to reuse this fetching logic across multiple parts of our app.

Fetching the organization data alone is straightforward and nicely encapsulated:
// composables/useOrganization.ts
export function useOrganization(id: MaybeRefOrGetter<string>) {
  return useFetch<Organization>(`/organizations/${id}`, {
    baseURL,
  });
};


Usage in a page:
// pages/organizations/[id].vue
const $route = useRoute();
const id = $route.params.id as string;

const { data } = await useOrganization(id);

if (!organization.value) {
  throw createError({ statusCode: 404, message: "Page not found" });
}


Where we’re stuck is how best to fetch and structure related event data. These events are tied to the organization.

One idea was to extend the composable like this:
// composables/useOrganization.ts
export function useOrganization(id: MaybeRefOrGetter<string>) {
  const orgResponse = useFetch<Organization>(`/organizations/${id}`, {
    baseURL,
  });

  function fetchEvents() {
    return useFetch<Event>(`/events?organization=${id}`, {
      baseURL,
    });
  }

  return {
    ...orgResponse,
    fetchEvents
  };
};


Then use it like this:
// pages/organizations/[id].vue
const { data, fetchEvents } = await useOrganization(id);
const { data: events } = fetchEvents();


This works, but by spreading the orgResponse, we lose the “thenable” behavior of useFetch. We’d like to keep the ability to await useOrganization(id) in page-level usage.

So I’m wondering:

- Is this an acceptable approach?
- Should we separate event logic into its own composable (e.g., useOrganizationEvents(id))?
- Is there a clean way to preserve the thenable behavior while extending the returned object?

Any best practices, patterns, or anti-patterns to consider would be much appreciated!
Was this page helpful?