Skip to content

Instantly share code, notes, and snippets.

@boring-dragon
Forked from Adamwaheed/useAPI.ts
Created June 9, 2023 19:15
Show Gist options
  • Select an option

  • Save boring-dragon/35825b7b080a2371f360bb18dfa64e70 to your computer and use it in GitHub Desktop.

Select an option

Save boring-dragon/35825b7b080a2371f360bb18dfa64e70 to your computer and use it in GitHub Desktop.

Revisions

  1. @Adamwaheed Adamwaheed created this gist Jun 9, 2023.
    183 changes: 183 additions & 0 deletions useAPI.ts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,183 @@
    import { build } from "nuxt";
    import { Data } from "~/types/generated";

    export const useAPI = (
    url: string,
    items: any,
    meta: any,
    item: any,
    status: any,
    errors: {}
    ) => {
    /**
    * This asynchronous function sends a GET request to the API to retrieve all items.
    *
    * @param query - An optional parameter, can be used to specify a specific API query.
    * @param _url - An optional parameter, can be used to specify a specific API endpoint.
    *
    * The method uses the `useHttp` function to send a GET request to the appropriate API endpoint,
    * constructed using the `generateApiUrl` function with provided `query` and `_url`.
    *
    * The response from the request is awaited and then used to update the status.
    * If the retrieval operation was successful, the value of `items` and possibly `meta`
    * (if the query included pagination) is updated with the response data.
    */
    const getAll = async (query?: any, _url?: string) => {
    const response = await useHttp(generateApiUrl(query, _url), {
    method: "get",
    });

    // Update the value of status based on the success of the response
    status.value = response.success;

    // If the retrieval operation was successful
    if (response.success) {
    // If pagination was included in the query, update 'items' with the data and 'meta' with the pagination info
    if (query !== undefined && "page" in query) {
    items.value = response.data.data;
    meta.value = response.data.meta;
    }
    // If pagination was not included in the query, update 'items' with the entire response data
    else {
    items.value = response.data;
    }
    }
    };

    /**
    * This asynchronous function sends a POST request to the API to create a new item.
    *
    * @param body - The data for the new item to be sent in the request body.
    * @param _url - An optional parameter, can be used to specify a specific API endpoint.
    *
    * The method uses the `useHttp` function to send a POST request to the appropriate API endpoint,
    * constructed using the provided `_url` and `body`.
    *
    * The response from the request is awaited and then used to update the status.
    * If the creation operation was successful, the value of `item` is updated with the response data,
    * and the new item is also pushed into the `items` array.
    */
    const create = async (body: any, _url?: string) => {
    const response = await useHttp(`${generateApiUrl(_url)}`, {
    method: "post",
    body,
    });

    // Update the value of status based on the success of the response
    status.value = response.success;

    // If the creation operation was successful, update the value of item and push the new item to items array
    if (response.success) {
    item.value = response.data;
    items.value.push(response.data);
    }
    };

    /**
    * This asynchronous function sends a GET request to the API to retrieve a specific item.
    *
    * @param url - The base URL of the API to interact with.
    * @param id - The ID of the item to be retrieved.
    *
    * The method uses the `useHttp` function to send a GET request to the appropriate API endpoint,
    * constructed using the provided `url` and `id`.
    *
    * The response from the request is awaited and then used to update the status
    * and potentially the item value, if the retrieval operation was successful.
    */
    const get = async (url: string, id: number) => {
    const response = await useHttp(`${url}/${id}`, {
    method: "get",
    });

    // Update the value of status based on the success of the response
    status.value = response.success;

    // If the retrieval operation was successful, update the value of item with the response data
    if (response.success) {
    item.value = response.data;
    }
    };

    /**
    * This asynchronous function sends a DELETE request to the API to remove a specific item.
    *
    * @param id - The ID of the item to be removed.
    *
    * The method uses the `useHttp` function to send a DELETE request to the appropriate API endpoint,
    * constructed using the provided `url` and `id`.
    *
    * The function returns the Promise returned by the `useHttp` function, allowing the caller to handle
    * the success or failure of the request.
    */
    const remove = async (id: number) => {
    return useHttp(`${url}/${id}`, {
    method: "delete",
    });
    };

    /**
    * This asynchronous function sends a PUT request to the API to update a specific item.
    *
    * @param id - The ID of the item to be updated. Can be of type string or number.
    * @param body - The data for the new item to be sent in the request body.
    * @param _url - An optional parameter, can be used to specify a specific API endpoint.
    *
    * The response from the request is awaited and then used to update the status
    * and potentially the item value, if the update operation was successful.
    */
    const update = async (id: string | number, body: any, _url?: string) => {
    const response = await useHttp(`${generateApiUrl(_url)}/${id}`, {
    method: "put",
    body,
    });

    // Update the value of status based on the success of the response
    status.value = response.success;

    // If the update operation was successful, update the value of item with the response data
    if (response.success) {
    item.value = response.data;
    }
    };

    /**
    * Generates a URL for an API request.
    *
    * @param query - Query parameters for the API request. It can be a string or an object.
    * @param _url - An optional parameter, can be used to specify a specific endpoint.
    * If 'query' is a string, it's treated as the URL. If 'query' is an object,
    * it's converted into URL parameters.
    *
    * The resulting URL is composed of the base URL, the specified endpoint,
    * and any query parameters, separated by slashes.
    *
    * @returns {string} - The generated API URL.
    */
    function generateApiUrl(query: any, _url?: string) {
    _url = typeof query === "string" ? query : _url;
    const tempURL = _url ? `${url}/${_url}` : url;
    let urlParam = "";

    if (query && typeof query === "object") {
    urlParam = `?${useQueryToUrl(query)}`;
    }

    const api_url = `${tempURL}${
    (query === undefined && query !== null) || Object.keys(query).length === 0
    ? ""
    : urlParam
    }`;
    return api_url;
    }

    return {
    status,
    errors,
    getAll,
    remove,
    create,
    update,
    get,
    };
    };
    68 changes: 68 additions & 0 deletions useHttp.ts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,68 @@
    export const useHttp = async (
    url: string,
    {
    method = "get",
    body = {},
    headers = {},
    fileUpload = false,
    }: {
    method?: string;
    body?: object;
    headers?: HeadersInit;
    fileUpload?: boolean;
    } = { method: "get" }
    ) => {
    const config = useRuntimeConfig();
    const token = useCookie("auth_token", {
    domain: config.public.session_domain,
    });
    let data = [];
    let error = null;
    let success = false;
    const initHeaders = new Headers(headers);
    var params: FormData | string = JSON.stringify(body);

    if (!initHeaders.has("Content-Type")) {
    initHeaders.append("Content-Type", "application/json");
    }
    if (token.value) {
    initHeaders.append("Authorization", `Bearer ${token.value}`);
    }
    if (fileUpload) {
    initHeaders.set("Content-Type", "multipart/form-data");
    const formData = new FormData();
    for (const key of Object.keys(body) as Array<keyof typeof body>) {
    formData.append(key, body[key]);
    }
    params = formData;
    }

    let options = {
    method,
    headers: initHeaders,
    body: method.toUpperCase() === "GET" ? undefined : params,
    };

    try {
    const response = await fetch(url, options);

    // wait for the response to be parsed as JSON
    if (response.ok) {
    const res = await response.json();
    data = res;
    success = true;
    } else {
    // Throw an error with status code and message
    const res = await response.json();
    error = res;
    success = false;
    }
    } catch (error) {
    success = false;
    }
    return {
    data,
    error,
    success,
    };
    };
    4 changes: 4 additions & 0 deletions useQueryToUrl.ts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,4 @@
    export const useQueryToUrl = (query: any) => {
    const keyValuePairs = Object.keys(query).map((key) => `${key}=${query[key]}`);
    return keyValuePairs.join("&");
    };
    49 changes: 49 additions & 0 deletions useWorkGroupStore.ts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,49 @@
    import { defineStore } from "pinia";
    import { Data } from "~/types/generated";

    // Export a function useWorkGroupStore to define a store named "workGroup"
    export const useWorkGroupStore = defineStore("workGroup", () => {
    // Access the runtime config with useRuntimeConfig
    const config = useRuntimeConfig();

    // Define the URL for the API using the runtime config
    const url = `${config.public.employment_api}/employer-work-groups`;

    // Define items as a ref to an empty array
    //The "items" variable stores the list of array items retrieved from the backend.
    //required state if using useAPI composable
    const items = ref<any>([]);

    // Define meta as a ref to an instance of Data.Meta
    //The "meta" variable stores data related to item pagination.
    //required state if using useAPI composable
    const meta = ref<Data.Meta>();

    // Define item as a ref to an instance of Data.EmployeeWorkgroup
    //The "item" variable stores a single item.
    //required state if using useAPI composable
    const item = ref<Data.EmployeeWorkgroup>();

    // Define httpStatus as a ref set initially to true
    //required state if using useAPI composable
    const httpStatus = ref(true);

    // Define errors as a ref initially set to null
    //required state if using useAPI composable
    const errors = ref(null);

    // Define http as the result of useAPI function
    const http = useAPI(url, items, meta, item, httpStatus, errors);

    // Define processing as a ref to a boolean, initially set to false
    const processing = ref<boolean>(false);

    // Return an object containing these variables
    return {
    errors,
    processing,
    http,
    items,
    item,
    };
    });