npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@nait-aits/fetch-state

v0.0.14

Published

A library to make loading data, and assigning it to states easier.

Downloads

55

Readme

fetch-state

These items are intended to make working with state loaded from http endpoints quicker to create and easier to work with.

Installation

npm install @nait-aits/fetch-state

Hooks and Providers

Setup

NaitFetchStateProvider

You can wrap your application (or specific components) in a NaitFetchStateProvider. If you don't, you won't be able to globally override default settings (baseUrl, getAuthToken, etc). You can still use these items, but they will need to be specified each call.

App.ts (or app/component entry point)

import { NaitFetchStateProvider } from "@nait-aits/fetch-state";

function App() {
  return (
    <NaitFetchStateProvider>
      <Control />
    </NaitFetchStateProvider>
  );
}

NaitFetchStateProvider config (optional)

If you have any overrides, you can specify the configuration defaults here as well. For example, you can set all endpoint calls to be POST and require authentication by default.

You only need to specify the items you are overriding/need.

For example:

<NaitFetchStateProvider
  config={{
    baseUrl: "http://google.com",
    defaultMethod: "GET",
    authenticationRequired: true,
  }}
>
  <Control />
</NaitFetchStateProvider>

Configuration Defaults

  • baseUrl: undefined;
  • defaultMethod: "POST";
  • authenticationRequired: false;
  • debug: false;
  • getAuthToken: undefined;

Authorization Tokens

If your application required Auth Bearere tokens, you can set the default get token hook here. Anytime a request that requires authentication is called, this hook will be called to get the token and append it to the header.

<NaitFetchStateProvider
  config={{
    getAuthToken: useTokenHook,
  }}
>
  <Control />
</NaitFetchStateProvider>

Integration with @nait-aits\azure-ad-auth

if you are using the package @nait-aits\azure-ad-auth, you can easily tap into the useGetToken hook and all auth is take care of for you (provided it is azure ad auth)

import "./App.css";
import TestAuth from "./TestAuth";
import { NaitAzureADAuthProvider, useGetToken } from "@nait-aits/azure-ad-auth";

import { NaitFetchStateProvider } from "@nait-aits/fetch-state";

function App() {
  return (
    <NaitAzureADAuthProvider>
      <NaitFetchStateProvider
        config={{
          getAuthToken: useGetToken,
        }}
      >
        <TestAuth />
      </NaitFetchStateProvider>
    </NaitAzureADAuthProvider>
  );
}

export default App;

Debug

If you are having issues, you can enable the debug panel by setting the debug value to true. This will output a div that contains the values that the provider is using.

useStateLoader

This hook is used to call get data from an endpoint, while tracking its status (start, end, error). It has a generic type, that specifies what type the data being returned is.

var [state, loadState, setState] = useStateLoader<ReturnType>({
  url: "someUrl",
});

It returns an array that contains the data state (of type StateItem<T>), the method load the data (loading does not happen automatically), and a setter in case you want to update the state yourself (not required, but may be useful).

Unless otherwise specified, the baseUrl above will prepend the url. The only required parameter is the url.

Note: The loadState method returns a cancellation function that can be used to cancel the call.

Usage

Here is a simple page that uses this hook.

import { useStateLoader } from "@nait-aits/fetch-state";
import { useEffect } from "react";

type Product = { name: string; id: number };
export function SamplePage() {
  //note: setProducts is shown here for demonstration purposes only.
  var [products, loadProducts, setProducts] = useStateLoader<Product[]>({
    url: `Products/GetAllProducts`,
    method: "GET",
    //specify data here
    data: {
      prop1: "Test",
    },
  });

  useEffect(() => {
    //by returning the cancellation function, this will
    //be automatically aborted when you leave this control
    return loadProducts({
      //or specify data here
      data: {
        prop1: "Test",
      },
    });
  }, []);

  return (
    <div>
      {products.loading && <div>Loading...</div>}
      {products.error && <div>Error: {products.error?.message}</div>}
      {products.data && (
        <div>
          {products.data.map((product) => (
            <div key={product.id}>{product.name}</div>
          ))}
        </div>
      )}
    </div>
  );
}

useLoadState

If, for whatever reason, you want to manage the start yourself, you can use useLoadState.

It is similar to useStateLoader, but you sepcify the setter. The state must be of type StateItem<T>.

It returns the method load the data. The only required parameter is the url.

Note: The load function returns a cancellation function that can be used to cancel the call, if needed.


var [data, setData] = useState<StateItem<ReturnType>>();

var loadData = useLoadState<ReturnType>({
  url: "someUrl",
}, setData);

...

var cancel = loadData();

//this will abort the call
cancel();

Usage

Here is a simple page that uses this hook.

import { StateItem, useLoadState } from "@nait-aits/fetch-state";
import { useEffect, useState } from "react";

type Product = { name: string; id: number };

export function SamplePage() {
  var [products, setProducts] = useState<StateItem<Product[]> | undefined>(
    undefined
  );

  var loadProducts = useLoadState<Product[]>(
    {
      url: `Products/GetAllProducts`,
    },
    setProducts,
    (event, data) => {
      //here you can do something with the event and data
      if (event === "end") {
        //do something
      }
    }
  );

  useEffect(() => {
    loadProducts();
  }, []);

  return (
    <div>
      {products?.loading && <div>Loading...</div>}
      {products?.error && <div>Error: {products?.error?.message}</div>}
      {products?.data && (
        <div>
          {products.data.map((product) => (
            <div key={product.id}>{product.name}</div>
          ))}
        </div>
      )}
    </div>
  );
}

useFetcher

While the first two are useful for state based operations, there are many times you want to make one off calls, and you only care it they were processed or not (i.e. deleting a record). That is where the useFetcher hook comes into play. It allows you to call an endpoint, and then do something with its result (or not, your call).

It is a simple hook to instantiate, requiring no parameters, and returns a fetch function you can call to access an endpoint.

The only required parameter is the url, but in order to know its result, you will need to tap into the onChange parameter.

Note: The fetch function returns a cancellation function that can be used to cancel the call, if needed.

var fetcher = useFetcher();
...
var cancel = fetcher.fetch<ReturnType>({
    url: someUrl,
    onChange: (event,data)=>{
        if(event === "end"){
            //do something (or not)
        }
    }
});

...

//cancel the fetch
cancel();

You can use the same fetcher multiple times (each with its own cancel token), it is not tied to a single state/endpoint.

Usage

Here is a simple page that uses this hook.

import { FetchError, useFetcher } from "@nait-aits/fetch-state";
import { useState } from "react";

type Product = { name: string; id: number };

export function SamplePage() {
  var fetcher = useFetcher();
  var [products, setProducts] = useState<Product[] | undefined>();

  return (
    <div>
      <button
        onClick={() => {
          fetcher.fetch<Product[]>({
            url: "Products/GetAllProducts",
            onChange: (event, data) => {
              //need to also make sure it isnt an error object
              if (event === "end" && !(data instanceof FetchError)) {
                setProducts(data);
              }
            },
          });
        }}
      >
        Load
      </button>
    </div>
  );
}