Skip to content

Commit 06d6f12

Browse files
loursbourgphryneas
andauthored
pass the ThunkArg to the idGenerator function (#1600)
Co-authored-by: Lenz Weber <mail@lenzw.de>
1 parent 98b9d9b commit 06d6f12

File tree

4 files changed

+32
-5
lines changed

4 files changed

+32
-5
lines changed

docs/api/createAsyncThunk.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ An object with the following optional fields:
9898

9999
- `condition(arg, { getState, extra } ): boolean | Promise<boolean>`: a callback that can be used to skip execution of the payload creator and all action dispatches, if desired. See [Canceling Before Execution](#canceling-before-execution) for a complete description.
100100
- `dispatchConditionRejection`: if `condition()` returns `false`, the default behavior is that no actions will be dispatched at all. If you still want a "rejected" action to be dispatched when the thunk was canceled, set this flag to `true`.
101-
- `idGenerator(): string`: a function to use when generating the `requestId` for the request sequence. Defaults to use [nanoid](./otherExports.mdx/#nanoid).
101+
- `idGenerator(arg): string`: a function to use when generating the `requestId` for the request sequence. Defaults to use [nanoid](./otherExports.mdx/#nanoid), but you can implement your own ID generation logic.
102102
- `serializeError(error: unknown) => any` to replace the internal `miniSerializeError` method with your own serialization logic.
103103
- `getPendingMeta({ arg, requestId }, { getState, extra }): any`: a function to create an object that will be merged into the `pendingAction.meta` field.
104104

packages/toolkit/src/createAsyncThunk.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ export type AsyncThunkOptions<
303303
*
304304
* @default `nanoid`
305305
*/
306-
idGenerator?: () => string
306+
idGenerator?: (arg: ThunkArg) => string
307307
} & IsUnknown<
308308
GetPendingMeta<ThunkApiConfig>,
309309
{
@@ -531,7 +531,9 @@ If you want to use the AbortController to react to \`abort\` events, please cons
531531
arg: ThunkArg
532532
): AsyncThunkAction<Returned, ThunkArg, ThunkApiConfig> {
533533
return (dispatch, getState, extra) => {
534-
const requestId = (options?.idGenerator ?? nanoid)()
534+
const requestId = options?.idGenerator
535+
? options.idGenerator(arg)
536+
: nanoid();
535537

536538
const abortController = new AC()
537539
let abortReason: string | undefined

packages/toolkit/src/tests/createAsyncThunk.test.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -815,6 +815,26 @@ describe('idGenerator option', () => {
815815
expect.stringContaining('fake-fandom-id')
816816
)
817817
})
818+
819+
test('idGenerator should be called with thunkArg', async () => {
820+
const customIdGenerator = jest.fn((seed) => `fake-unique-random-id-${seed}`)
821+
let generatedRequestId = ''
822+
const asyncThunk = createAsyncThunk(
823+
'test',
824+
async (args: any, { requestId }) => {
825+
generatedRequestId = requestId
826+
},
827+
{ idGenerator: customIdGenerator }
828+
)
829+
830+
const thunkArg = 1
831+
const expected = 'fake-unique-random-id-1'
832+
const asyncThunkPromise = asyncThunk(thunkArg)(dispatch, getState, extra)
833+
834+
expect(customIdGenerator).toHaveBeenCalledWith(thunkArg)
835+
expect(asyncThunkPromise.requestId).toEqual(expected)
836+
expect((await asyncThunkPromise).meta.requestId).toEqual(expected)
837+
})
818838
})
819839

820840
test('`condition` will see state changes from a synchronously invoked asyncThunk', () => {

packages/toolkit/src/tests/createAsyncThunk.typetest.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -433,10 +433,15 @@ const anyAction = { type: 'foo' } as AnyAction
433433
// @ts-expect-error
434434
const shouldFailNumWithoutArgs = createAsyncThunk('foo', () => {}, { idGenerator: returnsNumWithoutArgs })
435435

436-
const returnsStrWithArgs = (foo: any) => 'foo'
436+
const returnsStrWithNumberArg = (foo: number) => 'foo'
437437
// prettier-ignore
438438
// @ts-expect-error
439-
const shouldFailStrArgs = createAsyncThunk('foo', () => {}, { idGenerator: returnsStrWithArgs })
439+
const shouldFailWrongArgs = createAsyncThunk('foo', (arg: string) => {}, { idGenerator: returnsStrWithNumberArg })
440+
441+
const returnsStrWithStringArg = (foo: string) => 'foo'
442+
const shoulducceedCorrectArgs = createAsyncThunk('foo', (arg: string) => {}, {
443+
idGenerator: returnsStrWithStringArg,
444+
})
440445

441446
const returnsStrWithoutArgs = () => 'foo'
442447
const shouldSucceed = createAsyncThunk('foo', () => {}, {

0 commit comments

Comments
 (0)