Neurophysiologically Pseudoscientific Manatee

    redux-waiter

    0.5.0 • Public • Published

    Redux Waiter

    NPM Build Status

    Installation

    npm i redux-waiter --save

    This gives you access to the reducer, constants, actions, and selectors available.

    Add to your combineReducers()

    import { reducer } from 'redux-waiter';
     
    const initialState = combineReducers({
      waiter: reducer,
    });
     
    const store = createStore(
      initialState,
      {},
      compose(applyMiddleware(...[thunk]))
    );

    NOTE: Ensure you have redux-thunk configured as middleware in your store implementation

    Waiter model description and defaults

    Each waiter initialized will have these properties.

    const model = {
      // incremented after each request
      id: 0,
     
      // your waiter's name
      name: null,
     
      // your request to track
      requestCreator: null,
     
      // the params for your request to use
      params: null,
     
      // the promise returned from the requestCreator
      request: null,
     
      // the result of the promise
      response: null,
     
      // the error if returned from the promise
      error: null,
     
      // true if the request is called a second time and isPending
      isRefreshing: false,
     
      // true when the request is pending
      isPending: false,
     
      // true when the request returns an error
      isRejected: false,
     
      // true when the request returns successfully
      isResolved: false,
     
      // true if the request resolves or rejects
      isCompleted: false,
     
      // true if the request is canceled
      isCanceled: false,
     
      // true if the request rejected, and is being called again
      isRetrying: false,
     
      // start time of request in milliseconds UTC
      startTime: null,
     
      // end time of request in milliseconds UTC
      endTime: null,
     
      // difference in milliseconds of start and end times
      elapsedTime: null,
     
      // last time the model changed in milliseconds UTC
      lastModified: null,
     
      // how many times the request has been called and returned an error
      // resets after a successful response
      attempts: 0,
    };

    connectWaiter

    import { connectWaiter } from 'redux-waiter'

    connectWaiter is a higher-order-component that connects your waiter promise to another component. You can listen in on waiter events and dispatch other actions. You can add custom views to different waiter states, as well as add custom actions to the mount and unmount lifecycle events

    Below is the full interface for connectWaiter, ordered in the sequence that the actions take place

    import { connectWaiter } from 'redux-waiter';
    import MyComponent from 'path/to/MyComponent';
    import notification from 'path/to/notification';
     
    const SearchRequestForm = connectWaiter({
      /* 
       * Configuration settings 
       */
     
      // name can be a string or a function with access to props 
      name: (props) => 'my-waiter-name',
     
      // requestCreator, your promise builder 
      requestCreator: (params, props) => yourAPI.getSomething(params),
     
      /* 
       * Alternate views 
       */
     
      pendingView: LoadingView,
      rejectedView: FailureView,
     
      /* 
       * Lifecycle configs and state change callbacks
       */
     
      // onMount
      onMount: (waiter, props) => {
        // Hey, we mounted!
        console.log('onMount', waiter)
      },
     
      // clear the waiter data when the component is added to the view
      clearOnMount: true,
     
      // create your promise request when mounting your component
      requestOnMount: true,
     
      // pass parameters to the request creator based on props
      requestOnMountParams: (props) => ({ name: 'First', last: 'Last' }),
     
      // like requestOnMountParams, but used to initialize the call to
      // the waiter again on props change
      requestOnPropsChange: (props) => ({ name: 'First', last: 'Last' }),
     
      // state change callbacks 
      onPending: (waiter, props) => {
        // And we're off! 
        console.log('onPending - ', waiter);
      },
      onResolve: (waiter, props) => {
        // Success!
        console.log('onResolve - ', waiter.response);
      },
      onReject: (waiter, props) => {
        // Oh no...error
        console.log('onReject - ', waiter.error);
      },
      onComplete: (waiter, props) => {
        // All done!
        console.log('onComplete - ', waiter);
      },
      onRefresh: (waiter, props) => {
        // We're updating our response!
        console.log('onRefresh - ', waiter)
      },
      onCancel: (waiter, props) => {
        // The waiter canceled, do what you need to clean up 
        console.log('onCancel - ', waiter)
      },
     
      // on unmount
      onUnmount: (waiter, props) => {
        // Say goodbye to your view! 
        console.log('onUnmount - ', waiter);
      },
     
      // clear the waiter data when the component is removed from view
      clearOnUnmount: true,
     
    })(MyComponent);

    Actions

    callWaiter(waiterName, { params, requestCreator })

    The call action will invoke the requestCreator with the supplied params and store all waiter processes to the waiterName given.

    import { callWaiter } from 'redux-waiter';
     
    dispatch(
      callWaiter('get-toy', {
        requestCreator: (params) => getToyPromise(params.id),
        params: { id: '1' },
      })
    );

    prepareWaiter(waiterName, { params, requestCreator })

    Prepare is the same as callWaiter, but it will only store up the params and request creator to the waiterName. It will not invoke the requestCreator until callWaiter(waiterName) is dispatched

    import { prepareWaiter } from 'redux-waiter'
    
    dispatch(
      prepareWaiter('get-toy', {
        requestCreator: (params) => getToyPromise(params.id),
        params: { id: '1'}
      })
    )
    
    // then somewhere else you can call it
    dispatch(callWaiter('get-toy'))
    

    clearWaiter(waiterName)

    Clear will reset the waiter as if it was never called. This removes all params, response, and error data. The waiter stays in the store and can be used again.

    import { clearWaiter } from 'redux-waiter';
     
    // In your redux environment
    dispatch(clearWaiter('waiter-name'));

    clearAll()

    Clear all the waiters in the store.

    import { clearAll } from 'redux-waiter';
     
    // In you redux environment
    dispatch(clearAll());

    destroyWaiter(waiterName)

    Destroy will remove the waiter from the store. It will not longer be accessible unless initialized again.

    import { destroyWaiter } from 'redux-waiter';
     
    // In you redux environment
    dispatch(destroyWaiter('waiter-name'));

    destroyAll()

    Destroy all the waiters in the store.

    import { destroyAll } from 'redux-waiter';
     
    // In you redux environment
    dispatch(destroyAll());

    Selectors

    getWaiter(state, waiterName)

    Get the waiter model from the store by it's name.

    import { getWaiter } from 'redux-waiter';
     
    // In your mapStateToProps somewhere
    (state) => getWaiter(state, 'get-toy');

    getWaiterResponse(state, waiterName)

    Get only the response of the promise by the waiter name. Returns null if no response has been set.

    import { getWaiterResponse } from 'redux-waiter';
     
    // In your mapStateToProps somewhere
    (state) => getWaiterResponse(state, 'get-toy');

    getWaiterError(state, waiterName)

    Get only the error of the promise by the waiter name. Returns null if no error has been set.

    import { getWaiterError } from 'redux-waiter';
     
    // In your mapStateToProps somewhere
    (state) => getWaiterError(state, 'get-toy');

    Example

    Valid Document Link

    Create your component with the connectWaiter

    import React from 'react';
    import axios from 'axios';
     
    import { connectWaiter } from 'redux-waiter';
     
    const ValidUrlLink = connectWaiter({
      // dynamic waiter name using props
      name: (props) => `link:${props.url}`,
     
      requestCreator: (params) => axios({ url: params.url }),
      requestOnMountParams: (props) => ({ url: props.url }),
     
      // alternate views for the Promise lifecycle
      pendingView: () => <span>...</span>,
      rejectedView: () => <span>Invalid link</span>,
    })((props) => <a href={props.url}>Click to View</a>);

    Implement your component in the JSX

    ... <ValidUrlLink url="https://link.to.pdf" />' ...

    Dependencies

    Due to the asynchronous nature of this library, redux-waiter requires that you have redux-thunk configured as middleware for your store.

    Install

    npm i redux-waiter

    DownloadsWeekly Downloads

    6

    Version

    0.5.0

    License

    MIT

    Unpacked Size

    83.1 kB

    Total Files

    26

    Last publish

    Collaborators

    • billyxs