Advertisement
Guest User

Untitled

a guest
Oct 21st, 2019
115
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import { useState, useCallback } from 'react';
  2. import useGetCurrentValue from 'Hooks/Common/useGetCurrentValue';
  3.  
  4. type TRemoteValidator<TArgs extends any[]> = (...args: TArgs) => Promise<boolean>;
  5.  
  6. const isDelayPending = (lastRequest: number, delay: number) => Date.now() - lastRequest < delay;
  7. const wasRequestCanceled = (currentRequest: number, lastRequest: number) => currentRequest !== lastRequest;
  8. const neverResolvedPromise = () => new Promise<boolean>((resolve) => { });
  9.  
  10. const useRemoteValidation = <TArgs extends any[]>(
  11.     remoteValidator: TRemoteValidator<TArgs>,
  12.     delay: number = 0,
  13. ) => {
  14.     const [isLoading, setIsLoading] = useState(false);
  15.     const [lastRequest, setLastRequest] = useState(0);
  16.  
  17.     const remoteValidatorRef = useGetCurrentValue(remoteValidator);
  18.     const lastRequestRef = useGetCurrentValue(lastRequest);
  19.  
  20.     const validate = useCallback<TRemoteValidator<TArgs>>(
  21.         (...args: TArgs) => {
  22.             const currentRequest = Date.now();
  23.  
  24.             setLastRequest(currentRequest);
  25.             setIsLoading(true);
  26.  
  27.             const currentRemoteValidatorPromise = () => remoteValidatorRef()(...args)
  28.                 .then((response) => response)
  29.                 .catch((error) => error)
  30.                 .then((result) => {
  31.                     if (wasRequestCanceled(currentRequest, lastRequestRef())) {
  32.                         return neverResolvedPromise();
  33.                     }
  34.  
  35.                     setIsLoading(false);
  36.  
  37.                     // this means that error occured, return is valid
  38.                     if (typeof result !== 'boolean') {
  39.                         console.log('Validation failed.', result);
  40.                         return true;
  41.                     }
  42.  
  43.                     return result;
  44.                 });
  45.  
  46.             return new Promise<boolean>((resolve) => {
  47.                 const timeoutCallback = () => {
  48.                     if (isDelayPending(lastRequestRef(), delay)) {
  49.                         return;
  50.                     }
  51.                     resolve(currentRemoteValidatorPromise());
  52.                 };
  53.  
  54.                 setTimeout(timeoutCallback, delay);
  55.             });
  56.         },
  57.         [
  58.             delay,
  59.             lastRequestRef,
  60.             setLastRequest,
  61.             setIsLoading,
  62.             remoteValidatorRef,
  63.         ]
  64.     );
  65.  
  66.     return {
  67.         isLoading,
  68.         validate,
  69.     };
  70. };
  71.  
  72. export default useRemoteValidation;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement