Skip to content

Commit a53849b

Browse files
committed
Rename thunk types and fields and export SerializedError
1 parent a11b380 commit a53849b

File tree

4 files changed

+45
-45
lines changed

4 files changed

+45
-45
lines changed

docs/api/createAsyncThunk.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ The `payloadCreator` function can contain whatever logic you need to calculate a
6868

6969
The `payloadCreator` function will be called with two arguments:
7070

71-
- `thunkArg`: a single value, containing the first parameter that was passed to the thunk action creator when it was dispatched. This is useful for passing in values like item IDs that may be needed as part of the request. If you need to pass in multiple values, pass them together in an object when you dispatch the thunk, like `dispatch(fetchUsers({status: 'active', sortBy: 'name'}))`.
71+
- `arg`: a single value, containing the first parameter that was passed to the thunk action creator when it was dispatched. This is useful for passing in values like item IDs that may be needed as part of the request. If you need to pass in multiple values, pass them together in an object when you dispatch the thunk, like `dispatch(fetchUsers({status: 'active', sortBy: 'name'}))`.
7272
- `thunkAPI`: an object containing all of the parameters that are normally passed to a Redux thunk function, as well as additional options:
7373
- `dispatch`: the Redux store `dispatch` method
7474
- `getState`: the Redux store `getState` method
@@ -110,7 +110,7 @@ interface PendingAction<ThunkArg> {
110110
payload: undefined
111111
meta: {
112112
requestId: string
113-
thunkArg: ThunkArg
113+
arg: ThunkArg
114114
}
115115
}
116116

@@ -119,7 +119,7 @@ interface FulfilledAction<ThunkArg, PromiseResult> {
119119
payload: PromiseResult
120120
meta: {
121121
requestId: string
122-
thunkArg: ThunkArg
122+
arg: ThunkArg
123123
}
124124
}
125125

@@ -129,26 +129,26 @@ interface RejectedAction<ThunkArg> {
129129
error: SerializedError | any
130130
meta: {
131131
requestId: string
132-
thunkArg: ThunkArg
132+
arg: ThunkArg
133133
aborted: boolean
134134
abortReason?: string
135135
}
136136
}
137137

138138
type Pending = <ThunkArg>(
139139
requestId: string,
140-
thunkArg: ThunkArg
140+
arg: ThunkArg
141141
) => PendingAction<ThunkArg>
142142

143143
type Fulfilled = <ThunkArg, PromiseResult>(
144144
payload: PromiseResult,
145145
requestId: string,
146-
thunkArg: ThunkArg
146+
arg: ThunkArg
147147
) => FulfilledAction<ThunkArg, PromiseResult>
148148

149149
type Rejected = <ThunkArg>(
150150
requestId: string,
151-
thunkArg: ThunkArg
151+
arg: ThunkArg
152152
) => RejectedAction<ThunkArg>
153153
```
154154

src/createAsyncThunk.test.ts

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,16 +39,16 @@ describe('createAsyncThunk', () => {
3939
it('accepts arguments and dispatches the actions on resolve', async () => {
4040
const dispatch = jest.fn()
4141

42-
let passedArgs: any
42+
let passedArg: any
4343

4444
const result = 42
4545
const args = 123
4646
let generatedRequestId = ''
4747

4848
const thunkActionCreator = createAsyncThunk(
4949
'testType',
50-
async (args: number, { requestId }) => {
51-
passedArgs = args
50+
async (arg: number, { requestId }) => {
51+
passedArg = arg
5252
generatedRequestId = requestId
5353
return result
5454
}
@@ -58,7 +58,7 @@ describe('createAsyncThunk', () => {
5858

5959
await thunkFunction(dispatch, undefined, undefined)
6060

61-
expect(passedArgs).toBe(args)
61+
expect(passedArg).toBe(args)
6262

6363
expect(dispatch).toHaveBeenNthCalledWith(
6464
1,
@@ -100,13 +100,11 @@ describe('createAsyncThunk', () => {
100100

101101
expect(dispatch).toHaveBeenCalledTimes(2)
102102

103-
console.log(dispatch.mock.calls)
104-
105103
// Have to check the bits of the action separately since the error was processed
106104
const errorAction = dispatch.mock.calls[1][0]
107105
expect(errorAction.error).toEqual(miniSerializeError(error))
108106
expect(errorAction.meta.requestId).toBe(generatedRequestId)
109-
expect(errorAction.meta.args).toBe(args)
107+
expect(errorAction.meta.arg).toBe(args)
110108
})
111109
})
112110

src/createAsyncThunk.ts

Lines changed: 28 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,22 @@ import { Dispatch } from 'redux'
22
import nanoid from 'nanoid'
33
import { createAction } from './createAction'
44

5-
type AsyncThunksArgs<S, E, D extends Dispatch = Dispatch> = {
5+
type BaseThunkAPI<S, E, D extends Dispatch = Dispatch> = {
66
dispatch: D
77
getState: S
88
extra: E
99
requestId: string
1010
signal: AbortSignal
1111
}
1212

13-
interface SimpleError {
13+
export interface SerializedError {
1414
name?: string
1515
message?: string
1616
stack?: string
1717
code?: string
1818
}
1919

20-
const commonProperties: (keyof SimpleError)[] = [
20+
const commonProperties: (keyof SerializedError)[] = [
2121
'name',
2222
'message',
2323
'stack',
@@ -27,7 +27,7 @@ const commonProperties: (keyof SimpleError)[] = [
2727
// Reworked from https://github.com/sindresorhus/serialize-error
2828
export const miniSerializeError = (value: any): any => {
2929
if (typeof value === 'object' && value !== null) {
30-
const simpleError: SimpleError = {}
30+
const simpleError: SerializedError = {}
3131
for (const property of commonProperties) {
3232
if (typeof value[property] === 'string') {
3333
simpleError[property] = value[property]
@@ -50,63 +50,61 @@ export const miniSerializeError = (value: any): any => {
5050
export function createAsyncThunk<
5151
ActionType extends string,
5252
Returned,
53-
ActionParams = void,
54-
TA extends AsyncThunksArgs<any, any, any> = AsyncThunksArgs<
53+
ThunkArg = void,
54+
ThunkAPI extends BaseThunkAPI<any, any, any> = BaseThunkAPI<
5555
unknown,
5656
unknown,
5757
Dispatch
5858
>
5959
>(
6060
type: ActionType,
6161
payloadCreator: (
62-
args: ActionParams,
63-
thunkArgs: TA
62+
arg: ThunkArg,
63+
thunkAPI: ThunkAPI
6464
) => Promise<Returned> | Returned
6565
) {
6666
const fulfilled = createAction(
6767
type + '/fulfilled',
68-
(result: Returned, requestId: string, args: ActionParams) => {
68+
(result: Returned, requestId: string, arg: ThunkArg) => {
6969
return {
7070
payload: result,
71-
meta: { args, requestId }
71+
meta: { arg, requestId }
7272
}
7373
}
7474
)
7575

7676
const pending = createAction(
7777
type + '/pending',
78-
(requestId: string, args: ActionParams) => {
78+
(requestId: string, arg: ThunkArg) => {
7979
return {
8080
payload: undefined,
81-
meta: { args, requestId }
81+
meta: { arg, requestId }
8282
}
8383
}
8484
)
8585

8686
const rejected = createAction(
8787
type + '/rejected',
88-
(error: Error, requestId: string, args: ActionParams) => {
88+
(error: Error, requestId: string, arg: ThunkArg) => {
89+
const aborted = error && error.name === 'AbortError'
8990
return {
9091
payload: undefined,
9192
error: miniSerializeError(error),
9293
meta: {
93-
args,
94+
arg,
9495
requestId,
95-
...(error &&
96-
error.name === 'AbortError' && {
97-
aborted: true,
98-
abortReason: error.message
99-
})
96+
aborted,
97+
abortReason: aborted ? error.message : undefined
10098
}
10199
}
102100
}
103101
)
104102

105-
function actionCreator(args: ActionParams) {
103+
function actionCreator(arg: ThunkArg) {
106104
return (
107-
dispatch: TA['dispatch'],
108-
getState: TA['getState'],
109-
extra: TA['extra']
105+
dispatch: ThunkAPI['dispatch'],
106+
getState: ThunkAPI['getState'],
107+
extra: ThunkAPI['extra']
110108
) => {
111109
const requestId = nanoid()
112110
const abortController = new AbortController()
@@ -117,26 +115,26 @@ export function createAsyncThunk<
117115
abortAction = rejected(
118116
{ name: 'AbortError', message: reason },
119117
requestId,
120-
args
118+
arg
121119
)
122120
dispatch(abortAction)
123121
}
124122

125123
const promise = (async function() {
126124
let finalAction: ReturnType<typeof fulfilled | typeof rejected>
127125
try {
128-
dispatch(pending(requestId, args))
126+
dispatch(pending(requestId, arg))
129127

130128
finalAction = fulfilled(
131-
await payloadCreator(args, {
129+
await payloadCreator(arg, {
132130
dispatch,
133131
getState,
134132
extra,
135133
requestId,
136134
signal: abortController.signal
137-
} as TA),
135+
} as ThunkAPI),
138136
requestId,
139-
args
137+
arg
140138
)
141139
} catch (err) {
142140
if (err && err.name === 'AbortError' && abortAction) {
@@ -145,10 +143,10 @@ export function createAsyncThunk<
145143
// return a copy of the dispatched abortAction, but attach the AbortError to it.
146144
return { ...abortAction, error: miniSerializeError(err) }
147145
}
148-
finalAction = rejected(err, requestId, args)
146+
finalAction = rejected(err, requestId, arg)
149147
}
150148

151-
// We dispatch "success" _after_ the catch, to avoid having any errors
149+
// We dispatch the result action _after_ the catch, to avoid having any errors
152150
// here get swallowed by the try/catch block,
153151
// per https://twitter.com/dan_abramov/status/770914221638942720
154152
// and https://redux-toolkit.js.org/tutorials/advanced-tutorial#async-error-handling-logic-in-thunks

src/index.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,4 +73,8 @@ export {
7373
Comparer
7474
} from './entities/models'
7575

76-
export { createAsyncThunk, unwrapResult } from './createAsyncThunk'
76+
export {
77+
createAsyncThunk,
78+
unwrapResult,
79+
SerializedError
80+
} from './createAsyncThunk'

0 commit comments

Comments
 (0)