@unleashit/async-handler
    TypeScript icon, indicating that this package has built-in type declarations

    0.6.14 • Public • Published

    Async Handler

    NPM npm (scoped) npm bundle size

    HOC that takes an async function and returns views for loading, no-data and error states. It accepts an optional method to check a cache before the async function is run.

    Install

    npm install @unleashit/async-handler
    

    Required peer dependencies: react.

    Example with render prop

    import React from 'react';
    import AsyncHandler from '@unleashit/async-handler';
    
    class ColorList extends React.Component {
      request() {
        return new Promise((resolve) => {
          setTimeout(() => {
            resolve(['red', 'green', 'blue', 'yellow', 'orange', 'black', 'white']);
          }, 1500);
        });
      }
    
      render() {
        return (
          <AsyncHandler request={this.request}>
            {(data) => <div>{data.join(', ')}</div>}
          </AsyncHandler>
        );
      }
    }
    
    export default ColorList;

    This will display default messages for loading, error or no results* as needed. Note that request should return a promise with just the data part of the response so AsyncHandler can know when to display the no results component.

    * no results meaning when an object with no keys or a zero length array is returned.

    HOC example using cache and optional components

    import { withAsyncHandler } from '@unleashit/async-handler';
    import MySpinner from './spinner';
    
    // data to fetch asynchronously, here for demo reasons
    const users = [
      {
        id: 1,
        name: 'joe',
        age: 30,
      },
      {
        id: 2,
        name: 'judy',
        age: 27,
      },
    ];
    
    // for demonstration, normally you might use
    // Redux or another decoupled place to store the cache.
    let userCache = null;
    
    const UserList = ({ data }) => {
      return (
        <ul>
          {data.map((item) => (
            <li key={item.id}>
              {item.name} is {item.age} years old.
            </li>
          ))}
        </ul>
      );
    };
    
    export default withAsyncHandler({
      request: () => {
        return new Promise((resolve) => {
          setTimeout(() => {
            userCache = { users, cacheDate: new Date() };
            resolve(users);
          }, 1500);
        });
      },
      cache: () => {
        return userCache && new Date() - userCache.cacheDate <= 5 * 1000
          ? userCache.users
          : null;
      },
      loaderComponent: <MySpinner foo={'bar'} />,
      noResultsComponent: <div>No user{"'"}s found.</div>,
      errorComponent: ({ error }) => (
        <div>Oops, there was a problem: {JSON.stringify(error)}</div>
      ),
    })(UserList);

    CSS

    Basic namespaced (BEM) css can be imported: import '@unleashit/async-handler/dist/async-handler.css'. CSS Module support is baked in. If you use CSS Modules you can import '@unleashit/async-handler/dist/async-handler.module.css' or import your own custom module targeting the internal classes and pass to the cssModule prop. Please see CSS in the main readme of the repo for more info.

    API and Props

    interface DefaultComponentProps {
      cssModule?: {
        [key: string]: string;
      };
      error?: any;
    }
    type DefaultComponent = (props?: DefaultComponentProps) => React.ReactNode;
    interface Props {
      request: () => Promise<any>;
      cache: () => object | any[] | false | null;
      loaderComponent: DefaultComponent;
      noResultsComponent: DefaultComponent;
      errorComponent: DefaultComponent;
      cssModule?: { [key: string]: string };
      children: (data: any) => any;
    }
    Name Type Description default
    request () => Promise Called if cache function exists and doesn't return a falsy value required
    cache () => object | any[] | false | null Optional function that should return a cache object or null (calls the request) n/a
    noResultsComponent () => React.ReactNode React component to override default no results message Nothing found.
    errorComponent ({ error }: {error: any} ) => React.ReactNode React component to override default error message default message with error displayed
    loaderComponent () => React.ReactNode React component to override the default loader Loading...
    cssModule { [key: string]: string } CSS Module object that optionally replaces default. Class names need to match expected names. undefined
    children (data: any) => any; Function to be called with data if request returns with results (AsyncHandler only) n/a

    Install

    npm i @unleashit/async-handler

    DownloadsWeekly Downloads

    4

    Version

    0.6.14

    License

    MIT

    Unpacked Size

    89.9 kB

    Total Files

    27

    Last publish

    Collaborators

    • unleashit