Created
August 10, 2025 12:14
-
-
Save AmoahDevLabs/6c4e52119bc8c3ac9399906a31640a8e to your computer and use it in GitHub Desktop.
Nuxt.js Composables; from messy to Optimization.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Before and after optimization | |
| // Before | |
| import { useAuthStore } from "@/stores/auth"; | |
| export const getAuthHeaders = async () => { | |
| const authStore = useAuthStore(); | |
| if (!authStore.hydrated) { | |
| authStore.init(); | |
| } | |
| await authStore.validateAndRefreshToken(); | |
| if (!authStore.accessToken) { | |
| throw new Error("No access token available. Please log in again."); | |
| } | |
| return { Authorization: `Bearer ${authStore.accessToken}` }; | |
| }; | |
| // After | |
| // useAuthHeaders.ts | |
| import { useAuthStore } from "@/stores/auth"; | |
| export const getAuthHeaders = async () => { | |
| const authStore = useAuthStore(); | |
| if (!authStore.hydrated) { | |
| authStore.init(); | |
| } | |
| await authStore.validateAndRefreshToken(); | |
| if (!authStore.accessToken) { | |
| throw new Error("No access token available. Please log in again."); | |
| } | |
| return { Authorization: `Bearer ${authStore.accessToken}` }; | |
| }; | |
| // useApiRequest.ts | |
| // composables/useApiRequest.ts | |
| import { ref } from "vue"; | |
| import { getAuthHeaders } from "@/composables/useAuthHeaders"; | |
| export function useApiRequest() { | |
| const loading = ref(false); | |
| const error = ref<string | null>(null); | |
| const apiRequest = async <T>(url: string, options: any = {}): Promise<T> => { | |
| loading.value = true; | |
| error.value = null; | |
| try { | |
| return await $fetch<T>(url, { | |
| headers: await getAuthHeaders(), | |
| ...options, | |
| }); | |
| } catch (err) { | |
| error.value = err instanceof Error ? err.message : String(err); | |
| console.error("API error:", err); | |
| throw err; | |
| } finally { | |
| loading.value = false; | |
| } | |
| }; | |
| return { | |
| apiRequest, | |
| loading, | |
| error, | |
| }; | |
| } | |
| // Finally: Optimized useGuests.ts | |
| // composables/useGuests.ts | |
| import { ref, computed } from "vue"; | |
| import type { Ref } from "vue"; | |
| import { getFullName } from "~/utils/names"; | |
| import { useApiRequest } from "~/composables/useApiRequest"; | |
| interface Guest { | |
| id: string; | |
| first_name: string; | |
| last_name: string; | |
| other_name?: string; | |
| sex: string; | |
| address?: string; | |
| city?: string; | |
| date_of_birth?: string; | |
| id_type?: string; | |
| id_number?: string; | |
| phone_number: string; | |
| email?: string; | |
| contact_name?: string; | |
| contact_phone?: string; | |
| } | |
| export function useGuests() { | |
| const config = useRuntimeConfig(); | |
| const apiBase = config.public.apiBase; | |
| // Use the centralized API composable | |
| const { apiRequest, loading, error } = useApiRequest(); | |
| const guests: Ref<Guest[]> = ref([]); | |
| const guest: Ref<Guest | null> = ref(null); | |
| const getGuests = async () => { | |
| guests.value = await apiRequest<Guest[]>(`${apiBase}/api/guests/`); | |
| }; | |
| const getGuest = async (id: string) => { | |
| guest.value = await apiRequest<Guest>(`${apiBase}/api/guests/${id}/`); | |
| }; | |
| const createGuest = async (payload: Partial<Guest>) => { | |
| return apiRequest<Guest>(`${apiBase}/api/guests/`, { | |
| method: "POST", | |
| body: payload, | |
| }); | |
| }; | |
| const updateGuest = async (id: string, payload: Partial<Guest>) => { | |
| return apiRequest<Guest>(`${apiBase}/api/guests/${id}/`, { | |
| method: "PATCH", | |
| body: payload, | |
| }); | |
| }; | |
| const deleteGuest = async (id: string) => { | |
| await apiRequest<void>(`${apiBase}/api/guests/${id}/`, { | |
| method: "DELETE", | |
| }); | |
| }; | |
| const guestFullName = computed(() => | |
| guest.value ? getFullName(guest.value) : "" | |
| ); | |
| const guestsWithFullNames = computed(() => | |
| guests.value.map((g) => ({ | |
| ...g, | |
| fullName: getFullName(g), | |
| })) | |
| ); | |
| return { | |
| guests, | |
| guest, | |
| loading, | |
| error, | |
| guestFullName, | |
| guestsWithFullNames, | |
| getGuests, | |
| getGuest, | |
| createGuest, | |
| updateGuest, | |
| deleteGuest, | |
| }; | |
| } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment