Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pass query args to prepareHeaders function #4638

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions docs/rtk-query/api/fetchBaseQuery.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ type FetchBaseQueryArgs = {
api: Pick<
BaseQueryApi,
'getState' | 'extra' | 'endpoint' | 'type' | 'forced'
>,
> & { args: string | FetchArgs },
) => MaybePromise<Headers | void>
fetchFn?: (
input: RequestInfo,
Expand Down Expand Up @@ -105,7 +105,7 @@ Typically a string like `https://api.your-really-great-app.com/v1/`. If you don'

_(optional)_

Allows you to inject headers on every request. You can specify headers at the endpoint level, but you'll typically want to set common headers like `authorization` here. As a convenience mechanism, the second argument allows you to use `getState` to access your redux store in the event you store information you'll need there such as an auth token. Additionally, it provides access to `extra`, `endpoint`, `type`, and `forced` to unlock more granular conditional behaviors.
Allows you to inject headers on every request. You can specify headers at the endpoint level, but you'll typically want to set common headers like `authorization` here. As a convenience mechanism, the second argument allows you to use `getState` to access your redux store in the event you store information you'll need there such as an auth token. Additionally, it provides access to `args`, `extra`, `endpoint`, `type`, and `forced` to unlock more granular conditional behaviors.

You can mutate the `headers` argument directly, and returning it is optional.

Expand All @@ -114,6 +114,7 @@ type prepareHeaders = (
headers: Headers,
api: {
getState: () => unknown
args: string | FetchArgs
extra: unknown
endpoint: string
type: 'query' | 'mutation'
Expand Down Expand Up @@ -303,8 +304,8 @@ The default response handler is `"json"`, which is equivalent to the following f

```ts title="Default responseHandler"
const defaultResponseHandler = async (res: Response) => {
const text = await res.text();
return text.length ? JSON.parse(text) : null;
const text = await res.text()
return text.length ? JSON.parse(text) : null
}
```

Expand Down
19 changes: 12 additions & 7 deletions packages/toolkit/src/query/fetchBaseQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ export type FetchBaseQueryArgs = {
api: Pick<
BaseQueryApi,
'getState' | 'extra' | 'endpoint' | 'type' | 'forced'
>,
> & { args: string | FetchArgs },
) => MaybePromise<Headers | void>
fetchFn?: (
input: RequestInfo,
Expand Down Expand Up @@ -164,9 +164,9 @@ export type FetchBaseQueryMeta = { request: Request; response?: Response }
* The base URL for an API service.
* Typically in the format of https://example.com/
*
* @param {(headers: Headers, api: { getState: () => unknown; extra: unknown; endpoint: string; type: 'query' | 'mutation'; forced: boolean; }) => Headers} prepareHeaders
* @param {(headers: Headers, api: { getState: () => unknown; args: string | FetchArgs; extra: unknown; endpoint: string; type: 'query' | 'mutation'; forced: boolean; }) => Headers} prepareHeaders
* An optional function that can be used to inject headers on requests.
* Provides a Headers object, as well as most of the `BaseQueryApi` (`dispatch` is not available).
* Provides a Headers object, most of the `BaseQueryApi` (`dispatch` is not available), and the args passed into the query function.
* Useful for setting authentication or headers that need to be set conditionally.
*
* @link https://developer.mozilla.org/en-US/docs/Web/API/Headers
Expand Down Expand Up @@ -212,7 +212,7 @@ export function fetchBaseQuery({
'Warning: `fetch` is not available. Please supply a custom `fetchFn` property to use `fetchBaseQuery` on SSR environments.',
)
}
return async (arg, api) => {
return async (args, api) => {
const { getState, extra, endpoint, forced, type } = api
let meta: FetchBaseQueryMeta | undefined
let {
Expand All @@ -223,9 +223,10 @@ export function fetchBaseQuery({
validateStatus = globalValidateStatus ?? defaultValidateStatus,
timeout = defaultTimeout,
...rest
} = typeof arg == 'string' ? { url: arg } : arg
} = typeof args == 'string' ? { url: args } : args

let abortController: AbortController | undefined, signal = api.signal
let abortController: AbortController | undefined,
signal = api.signal
if (timeout) {
abortController = new AbortController()
api.signal.addEventListener('abort', abortController.abort)
Expand All @@ -242,6 +243,7 @@ export function fetchBaseQuery({
config.headers =
(await prepareHeaders(headers, {
getState,
args,
extra,
endpoint,
forced,
Expand Down Expand Up @@ -297,7 +299,10 @@ export function fetchBaseQuery({
}
} finally {
if (timeoutId) clearTimeout(timeoutId)
abortController?.signal.removeEventListener('abort', abortController.abort)
abortController?.signal.removeEventListener(
'abort',
abortController.abort,
)
}
const responseClone = response.clone()

Expand Down
6 changes: 4 additions & 2 deletions packages/toolkit/src/query/tests/fetchBaseQuery.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -799,16 +799,17 @@ describe('fetchBaseQuery', () => {
})

test('prepareHeaders provides extra api information for getState, extra, endpoint, type and forced', async () => {
let _getState, _extra, _endpoint, _type, _forced
let _getState, _args: any, _extra, _endpoint, _type, _forced

const baseQuery = fetchBaseQuery({
baseUrl,
fetchFn: fetchFn as any,
prepareHeaders: (
headers,
{ getState, extra, endpoint, type, forced },
{ getState, args, extra, endpoint, type, forced },
) => {
_getState = getState
_args = args
_endpoint = endpoint
_type = type
_forced = forced
Expand Down Expand Up @@ -845,6 +846,7 @@ describe('fetchBaseQuery', () => {
await doRequest()

expect(_getState).toBeDefined()
expect(_args!.url).toBe('/echo')
expect(_endpoint).toBe('someEndpointName')
expect(_type).toBe('query')
expect(_forced).toBe(true)
Expand Down