How do you pass arguments to createAsyncThunk in redux toolkit?
Asked Answered
O

5

36

So i'm new to redux-toolkit and I want to do something really simple. I want to send some data on a POST request via this helper function. so I tried this

export const submitPaymentToServer = createAsyncThunk(
    'data/fetchAll',
    async ({ name, data }) => {
        return fetch('/payments', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({
                name,
                data,
            }),
        })
            .then((res) => res.json())
            .then((res) => res)
    },
)

but when I call it like so

    dispatch(
        submitPaymentToServer({
            name,
            data,
        }),
    )

typescript complains saying I don't have the right number of arguments. so how am I suppose to pass args to this function? or what is the way to do this with toolkit?

Objectivism answered 8/11, 2020 at 20:32 Comment(0)
P
48

This is what React-Redux says when you are using createAsyncThunk

You can only pass one argument to the thunk when you dispatch it. If you need to pass multiple values, pass them in a single object

So instead of

export const submitPaymentToServer = createAsyncThunk(
    'data/fetchAll',
    async ({ name, data }) => { // here you have two arguments
        return fetch('/payments', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({
                name,
                data,
            }),
        })
            .then((res) => res.json())
            .then((res) => res)
    },
)

You can only have one argument:

export const submitPaymentToServer = createAsyncThunk(
    'data/fetchAll',
    async (yourData) => {
        const {name, data} = yourData;
        return fetch('/payments', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({
                name,
                data,
            }),
        })
            .then((res) => res.json())
            .then((res) => res)
    },
)

Destructure your object inside the thunk call.

Reference: here

Preoccupancy answered 7/6, 2021 at 17:55 Comment(4)
This is incorrect. A destructured object in the params is still just one object/param. Doesn't matter if you do it in () or in body same thing logically. createAsyncThunk does only accept one param, but it doesn't care about your destructuring.Speedway
wow, have to sift through the docs for this... thanksGabby
This is same thing, read object destructuring ...Apparently
Even though the code comment "here you have two arguments" is not correct because it is one argument for JavaScript, the solution still fixes the error for TypeScript. With the solution the TypeScript error "Property 'name' does not exist on type 'void'." disappears.Fabrianna
T
20

You need to actually give these arguments a type:

export const submitPaymentToServer = createAsyncThunk(
    'data/fetchAll',
     async ({ name, data }: { name: string, data: MyDataType }) => {
        return fetch('/payments', {

If you are using JavaScript with TypeScript only in the IDE, you can add a docblock for that:

const thunk2 = createAsyncThunk(
  'data/fetchAll',
  /**  @param arg {{ name: string, data: MyDataType }} */
  (arg) => {
    return fetch('/payments', {
  
Thrift answered 10/11, 2020 at 5:58 Comment(2)
but this function was a js file ha. I still don't see why it complained? it wasn't complaining about the types of the arguments, it was complaining about the amount of args which was weirdObjectivism
Well, usually the amount of arguments is derived from the types, the fallback type being the TypeScript void, meaning "no argument". But that should not happen with pure JavaScript though. What IDE are you using?Thrift
C
4

I found this in the TypeScript Redux documentation

const fetchUserById = createAsyncThunk<
  // Return type of the payload creator
  MyData,
  // First argument to the payload creator
  number
>('users/fetchById', async (userId, thunkApi) => {
  const response = await fetch(`https://reqres.in/api/users/${userId}`, {
    headers: {
      Authorization: `Bearer ${thunkApi.extra.jwt}`,
    },
  })
  return (await response.json()) as MyData
})

The argument passed into createAsyncThunk is userId which I've defined with type number.

Cryology answered 15/2, 2022 at 10:31 Comment(0)
S
1

If you are using typescript, consider adding createAsyncThunk() types according to docs. to see if this works for you add:

createAsyncThunk
    <any, any, any>(...)

and don't forget to use proper typing based on: https://redux-toolkit.js.org/api/createAsyncThunk

Socle answered 15/1, 2023 at 11:35 Comment(0)
T
0

According to redux toolkit documentation

Single argument must be passed to thunk action creator and if you need to pass multiple values, pass within single object

you can fix it like this:

       export const submitPaymentToServer = createAsyncThunk(
    'data/fetchAll',
    async (para) => {
   const { name, data } = para
        return fetch('/payments', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({
                name,
                data,
            }),
        })
            .then((res) => res.json())
            .then((res) => res)
    },
)

you dispatch it like this:

dispatch({name: '', data: ...}) and pass the AppDispatch that is imported from store.ts to const dispatch = useDispatch<AppDispatch>();

Tibetan answered 15/2, 2024 at 18:7 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.