All files / client ApiCall.ts

100% Statements 32/32
100% Branches 25/25
100% Functions 7/7
100% Lines 29/29

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158  3x       3x 17x             7x         7x 7x 7x   7x                         9x 9x 2x               7x                               3x 3x     2x               1x                           3x 3x 2x               1x                   2x 2x 1x               1x                   10x   6x             4x   2x                 2x                    
import { ErrorResponse, ResponseData } from "../config/commonResponse";
import { BaseApi } from "./BaseApi"; // Import the base class for API calls
import { AxiosError } from "axios"; // Import Axios types for response and error handling
 
// Class to handle API requests and responses, extending the BaseApi
export class ApiCall extends BaseApi {
  private responseFunction = <T>(
    success: boolean,
    data: T,
    message?: string,
    detailMessage?: string,
    code?: string
  ): ResponseData<T> => {
    const response: ResponseData<T> = {
      success,
      data,
    };
 
    if (message) response.message = message;
    if (detailMessage) response.detailMessage = detailMessage;
    if (code) response.code = code;
 
    return response;
  };
 
  /**
   * GET method to fetch data from an API endpoint.
   * @param endpoint - API endpoint to make the request.
   * @param params - Query parameters to include in the request (optional).
   * @returns A promise resolving to the API response.
   */
  async getData<T>(
    endpoint: string,
    params: Record<string, any> = {}
  ): Promise<ResponseData<T>> {
    try {
      const response = await this.axiosInstance.get(endpoint, { params });
      return this.responseFunction(
        true,
        response.data.data,
        response.data.message,
        response.data.detailMessage,
        response.data.code
      );
    } catch (error) {
      throw this.handleError(error as AxiosError<ErrorResponse>);
    }
  }
 
  /**
   * POST method to send data to an API endpoint.
   * @param endpoint - API endpoint to make the request.
   * @param data - Payload to send in the request body (optional).
   * @param params - Query parameters to include in the request (optional).
   * @returns A promise resolving to the API response.
   */
  async postData<T>(
    endpoint: string,
    data: Record<string, any> = {},
    params: Record<string, any> = {}
  ): Promise<ResponseData<T>> {
    try {
      const response = await this.axiosInstance.post(endpoint, data, {
        params,
      });
      return this.responseFunction(
        true,
        response.data.data,
        response.data.message,
        response.data.detailMessage,
        response.data.code
      );
    } catch (error) {
      throw this.handleError(error as AxiosError<ErrorResponse>);
    }
  }
 
  /**
   * PUT method to update data on an API endpoint.
   * @param endpoint - API endpoint to make the request.
   * @param data - Payload to send in the request body (optional).
   * @returns A promise resolving to the API response.
   */
  async putData<T>(
    endpoint: string,
    data: Record<string, any> = {}
  ): Promise<ResponseData<T>> {
    try {
      const response = await this.axiosInstance.put(endpoint, data);
      return this.responseFunction(
        true,
        response.data.data,
        response.data.message,
        response.data.detailMessage,
        response.data.code
      );
    } catch (error) {
      throw this.handleError(error as AxiosError<ErrorResponse>);
    }
  }
 
  /**
   * DELETE method to remove data from an API endpoint.
   * @param endpoint - API endpoint to make the request.
   * @returns A promise resolving to the API response.
   */
  async deleteData<T>(endpoint: string): Promise<ResponseData<T>> {
    try {
      const response = await this.axiosInstance.delete(endpoint);
      return this.responseFunction(
        true,
        response.data.data,
        response.data.message,
        response.data.detailMessage,
        response.data.code
      );
    } catch (error) {
      throw this.handleError(error as AxiosError<ErrorResponse>);
    }
  }
 
  /**
   * Custom error handling method to format errors.
   * @param error - Axios error object containing details of the error.
   * @returns A formatted error object.
   */
  private handleError(error: AxiosError<ErrorResponse>) {
    if (error.response) {
      // Server-side error
      return {
        success: error.response?.data?.success || false, // Success flag from response, default to false
        code: error.response?.data?.code || null, // Response code or null if not provided
        data: error.response?.data?.data || null, // Response data or null
        message: error.response?.data?.message || "Unknown server error", // Response message or default
        error: error.response?.data?.error || "Unknown error", // Error details or default
      };
    } else if (error.request) {
      // Network error (no response received)
      return {
        success: false,
        code: null,
        data: null,
        message: "Network error, no response received", // Network-specific error message
        error: error.message || "Network error", // Error message from the Axios request
      };
    } else {
      // Other types of errors
      return {
        success: false,
        code: null,
        data: null,
        message: "An error occurred", // Generic error message
        error: error.message || "Unknown error", // Error message details
      };
    }
  }
}