Skip to content

Supercharge your native fetch() method with enhanced flexibility and an integrated caching system, which can be seamlessly used within requests or as a standalone feature.

License

Notifications You must be signed in to change notification settings

ahmedragab20/ar-catch

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

89 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

โš ๏ธ It's important to know that it's now deprecated with another repo: very-good-fetch โš ๏ธ

Supercharge your native fetch() method with enhanced flexibility and an integrated caching system, which can be seamlessly used within requests or as a standalone feature.

npm version Install size Minified + GZipped

NPM

Table of Contents

Installation

Package manager

Using npm:

npm install ar-catch

Using yarn:

yarn add ar-catch

Using pnpm:

pnpm install ar-catch

Features

  • super powered fetch()๐Ÿš€ - The goal behind the library is to provide a supercharged fetch() method, with flexible syntax and some other cool features such as caching, which can be used within requests or as a standalone feature and interceptors, interceptors are functions that are called before and after a request is made, they can be used to modify the request or response objects, or to handle errors, and state management, which is a feature that allows you to store data in a global state and access it from anywhere in your application, etc.
  • caching system๐Ÿ“ฎ - The library provides a simple caching system, which can be used within requests or as a standalone feature, it allows you to cache responses and retrieve them later. will talk about it in more details later but it's good to know that it will more advanced in the future.
  • interceptors ๐Ÿ‘จ๐Ÿปโ€โœˆ๏ธ - Interceptors are functions that are called before and after a request is made, they can be used to modify the request or response objects, or to handle errors.
  • state management ๐Ÿฌ - State management is a feature that allows you to store data in a global state and access it from anywhere in your application. just to mention, it sill experimental and not fully supported yet but it will be in the future.
  • flexible syntax ๐Ÿค๐Ÿป - The library provides a flexible syntax, which allows you to use it in different ways
  • lightweight ๐Ÿ‹๐Ÿปโ€โ™‚๏ธ - The library is very lightweight, it's only 4 kB minified and gzipped.
  • no dependencies ๐Ÿ––๐Ÿป - The library has no dependencies, it's completely standalone.
  • typescript support ๐Ÿ’™ - The library is written fully in typescript, so it has a built-in typescript support.
  • developer friendly โค๏ธ - The library is developer friendly, it has a very clean and well documented codebase, and it's open source, so you can contribute to it if you want.

Usage

The first step is recommended in the big projects!

  1. Create a file called api.js or api.ts in your project's root directory.

    // (file_name).config.ts;
    
    import arcatch from "ar-catch";
    
    const $catch = arcatch.config({
      baseURL: "your.base.url",
      alias: "$any_name",
      onReq: (req) => {
        /* Request */
      },
      onRes: (res) => {
        /* Response */
      },
      onErr: (err) => {
        /* Error */
      },
    });
    
    // will return the instance of the library,
    // that you can use to call an API with
    // or have a access to the config object
    console.log($catch);
    
    // now you're Done ๐ŸŽ‰
  2. go to where you wanna use the library

    import arcatch from "ar-catch";
    
    const response = await arcatch.$catch({
      // we name this way of using the library "Object Oriented" Usage
      // (sorry about the name๐Ÿ˜‚)
      // ...options
    });
    
    // or
    
    const response = await arcatch.$catch(url, {
      // we name this way of using the library "Direct URL" Usage
      // ...options
    });
    
    `๐Ÿ“‘ NOTE:: any option you set in the config file, like baseURL, header, ...etc will be applied on any request`;

Object Oriented Usage

import arcatch from "ar-catch";

const getTodo = async () => {
    const response = await arcatch.$catch({
      // this is the default method, so you don't have to specify it
      method: "GET",
      /**
       * here you have two options
       * 1. you can use the "ep" property, which stands for "endpoint"
       * 2. you can use the "fullPath" property, which stands for "full path"
       * it's important to know that you can't use both of them at the same time
       *
       * will discuss the difference between them later in the options table section.
       */
      fullPath: URL,

      // the response type, and it's optional, the default value is "json"
      // available options are: "json", "text", "blob", "arrayBuffer", "formData"
      resType: "json",

      // this options object will be combined with the default options object
      // but it will override the default options object if there's a conflict
      // ex: if you have a "headers" property in the default options object with a value of "content-type: "something not similar to this one", and you have a "headers" property in this object with a value of "content-type: "application/json", the value of the "headers" property in the default options object will be overridden with the value of the "headers" property in this object
      options: {
        headers: { "Content-Type": "application/json" },
        // the GET method doesn't support a body,
        // but you can still use it and it'll be handled in the background
        // to fit the fetch() method syntax
        body: {
          products: [
            {
              id: 1,
              quantity: 1,
            },
          ],
        },

        `๐Ÿ“‘ NOTE:: you still can send any other options that available in the fetch() method`
      },
    });
}

Direct URL Usage

import arcatch from "ar-catch";

const response = await arcatch.$catch("carts", {
  // the difference that i should mention here is that
  // the custom options object will include the options that will defined how your request will be handled
  // and anything outside of it will be sent to the fetch() method directly

  customOptions: {
    cache: "PER-SESSION", // the caching strategy, and this will be discussed in a whole section later
    useWithBaseURL: true, // will treat the "carts" as the endpoint not the full path
  },
});

API

config()

config() is a function that you can use to configure the library, and it has the following options:

  1. baseURL - The base URL of your API, and it's optional.
  2. alias - The alias that you can use to access the library anywhere in your application.
  3. onReq - The function that will be called before the request is made, and it's optional.
  4. onRes - The function that will be called after the request is made, and it's optional.
  5. onErr - The function that will be called if there's an error, and it's optional.

$catch()

$catch() is the main function of the library, it's the function that you'll use to send requests, and it has two ways to use it, the first one is the "Object Oriented" Usage, and the second one is the "Direct Link" Usage, and you've already seen both of them.

useCache()

useCache() is a function that you can use to cache your something based on key and value, and it has three caching strategies, which are:

  • PER-SESSION - The cache will be cleared when the user closes the tab or the browser.
  • RELOAD - The cache will be cleared when the user reloads the page.
  • NO-CACHE - Until this moment it's used as the default value, and it's basically just Doesn't do anything. but later on it'll be used to analyze the request and decide whether to cache it or not. or to track the request and cache it if it's repeated. or to help with things like performance, etc. but for now, it's just a placeholder.

example

import arcatch from "ar-catch";

const cache = arcatch.useCache("RELOAD"); // with that being done, any cache that will be set by the {cache} instant will be cleared when the user reloads the page.

`๐Ÿ“‘ NOTE:: You can use more that one instance to have all the power possible, or you can create set the cache strategy dynamic as well and it'll work perfectly as well`;

cache.set("key", "value");
cache.isCached("key"); // true/false

console.log(cache.getCachedKeys());
console.log(cache.get("key"));
cache.clearAllCaches();

console.log(cache.getCachedKeys());
console.log(cache.get("key"));

$config() options table

Property Type Description
baseURL string The base url that will be used with every request.
alias string The alias that will be used to access the library anywhere in your application.
defaultOptions object The default options that will be used with every request.
onReq function The function that will be called when the request is sent.
onRes function The function that will be called when the response is received.
onErr function The function that will be called when the error is received.

$catch() options object table

Object Oriented Usage

Property Type Description
method string The method that will be used with the request.
ep string The endpoint that will be used with the request.
fullPath string The full path that will be used with the request.
options object The options that will be used with the request.

Direct URL Usage

Property Type Description
customOptions object The options that will be used with the request.

issues you might encounter

1- if you're using the alias feature inside a typescript file, and you got an error that says "type is not defined", you can fix it by adding this line to the top of your file, or on the main file of your application (more recommended)

hopefully this gonna be fixed soon๐Ÿ’š

declare global {
  interface Window {
    [your choosen alias]: any;
  }
}

`๐Ÿ“ฎ [one more thing related to this point]`
// > this is not a bug, but just wanted to give you a hint to take advantage of it

// if you struggled with accessing the window object, you can use this one
function waitForWindowObject() {
  return new Promise((resolve, reject) => {
    // Check if the window object is already loaded
    if (document.readyState === "complete") {
      resolve(window); // Return the window object
    } else {
      // If the window is not yet loaded, add an event listener to wait for it
      window.addEventListener("DOMContentLoaded", () => {
        resolve(window); // Return the window object once it's loaded
      });
    }
  });
}

Final Words

The documentation should give you an over view on how to get started with the library, but in the code you'll find more hints and messages that will help you to understand what each piece of code does`

if you stuck somewhere, or got confused, just hover of the name of the function or the variable and you'll find a message that will help you to understand what it does

License

MIT ยฉ Ahmed Ragab

Support

If you like this project, you can support me by giving it a star and sharing it with your friends โญ๐Ÿค๐Ÿป

Contributing

If you have any idea, you can open an issue and let me know about it, or you can open a pull request and contribute.

Special Thanks

Alhamdulillah for everything ๐Ÿ’š

profit Mohamed (peace be upon him) said: "You will not be a true believer until you love for your brother what you love for yourself." [Sahih Al-Bukhari]

May Allah bless you all, and thanks for reaching this point ๐Ÿ’š

About

Supercharge your native fetch() method with enhanced flexibility and an integrated caching system, which can be seamlessly used within requests or as a standalone feature.

Resources

License

Stars

Watchers

Forks

Packages

No packages published