Home > Mobile >  How to use baseQuery outside of createApi in redux-toolkit
How to use baseQuery outside of createApi in redux-toolkit

Time:06-16

In order to reduce my app size, I want to remove axios from my redux-toolkit async thunks. Also, I would like to use my baseQuery function, since it has the global headers of my application.

My current async thunk (using axios):

export const loginAsyncThunk = createAsyncThunk<loginResponse, loginArgs>(
  'session/login',
  ({ username, password }) => new Promise((resolve, reject) => {
    axios.post(
      ROUTES.LOGIN(),
      { email: username, password }
    )
      .then((response) => resolve(response.data))
      .catch((error: AxiosError | typeof Error) => {
        if (axios.isAxiosError(error)) {
          reject(error.response?.data)
        }
        reject(error)
      })
  })
)

Trying to implement it with baseQuery, I get an error:

export const baseQuery = fetchBaseQuery({
  baseUrl: ROUTES.API_HOST,
  prepareHeaders: (headers, api) => {
    // app global headers
    headers.set('Content-Type', `application/json`)
    return headers
  },
})

export const loginAsyncThunk = createAsyncThunk<loginResponse, loginArgs>(
  'session/login',
  ({ username, password }) => new Promise((resolve, reject) => {
    const calledBaseQuery = baseQuery({
      url: ROUTES.LOGIN(),
      body: { email: username, password },
      // @ts-ignore: What should I do with following "api" and "extraOptions"?
    }, undefined, undefined)
    console.log(calledBaseQuery) // Promise {<rejected>: TypeError: Cannot read property 'signal' of undefined}
  })
)

CodePudding user response:

You pretty much can't - unless you build api yourself, which I would not really recommend since in the future at any point api can get additional properties.

Honestly, my question the other way round would be "why don't you make this a mutation instead?". You can add matchers to a mutation's fulfilled action in extraReducers very similarly like you'd do with an asyncThunk, so not a lot of your code would change.

You can see that in this example:

extraReducers: (builder) => {
    builder.addMatcher(
      api.endpoints.login.matchFulfilled,
      (state, { payload }) => {
        state.token = payload.token
        state.user = payload.user
      }
    )
  },
  • Related