Red Baron
Red Baron

Reputation: 7652

How do you pass arguments to createAsyncThunk in redux toolkit?

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?

Upvotes: 37

Views: 53419

Answers (5)

kaleb_coder
kaleb_coder

Reputation: 1

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>();

Upvotes: 0

Archer
Archer

Reputation: 21

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

Upvotes: 1

jhancock532
jhancock532

Reputation: 392

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.

Upvotes: 4

Shiqi
Shiqi

Reputation: 1015

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

Upvotes: 47

phry
phry

Reputation: 44086

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', {
  

Upvotes: 21

Related Questions