rtk-incubator / rtk-query

Data fetching and caching addon for Redux Toolkit
https://redux-toolkit.js.org/rtk-query/overview
MIT License
626 stars 31 forks source link

fix: baseQuery snippet in createApi documentation #157

Closed tevariou closed 3 years ago

tevariou commented 3 years ago

Refers to https://github.com/rtk-incubator/rtk-query-codegen/issues/34

codesandbox-ci[bot] commented 3 years ago

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit a225694257d880ae280cc10a130705a98bae81bb:

Sandbox Source
React Configuration
React Typescript Configuration
rtk-query-demo Configuration
svelte-app-rtk-simplequery-demo Configuration
gfortaine commented 3 years ago

That's right, it looks like that these changes were needed. On our side, we are using this snippet for auth. A few comments :

import { Semaphore } from "@shopify/semaphore";

const fetchMutex = new Semaphore(1);

const baseQueryWithReauth: BaseQueryFn<
  string | FetchArgs,
  unknown,
  FetchBaseQueryError
> = async (args, api, extraOptions) => {
  const permit = await fetchMutex.acquire();

  try {
    const { getState, dispatch } = api;
    const token = (getState() as RootState).auth.token;
    let result;

    if (token?.expires_at > Date.now())
      result = await baseQuery(args, api, extraOptions);

    if (
      token?.expires_at <= Date.now() ||
      (result.error && result.error.status === "401")
    ) {
      // try to get a new token
      const refreshResult = await baseQuery("/refreshToken", api, extraOptions);

      if (refreshResult.data) {
        // store the new token
        dispatch(setToken(refreshResult.data));
        // retry the initial query
        result = await baseQuery(args, api, extraOptions);
      } else {
        dispatch(loggedOut());
      }
    }

    return result;
  } finally {
    permit.release();
  }
};