Redux RTK query invalidatesTags not called after mutation
Asked Answered
M

2

7

I've been trying to figure out why tag invalidation is not working and added some logging. The providesTags in getMe works fine, but invalidatesTags in login is never called. What might be wrong?

I have a redux RTK query API like this:

const baseQuery = fetchBaseQuery({
  baseUrl: baseUrl,
  prepareHeaders: (headers, { getState }) => {
    const token = getState().auth.token
    if (token) {
      headers.set('authorization', `Bearer ${token}`)
    }
    return headers
  },
})

export const api = createApi({
  baseQuery: baseQuery,
  tagTypes: ['User'],
  endpoints: build => ({
    login: build.mutation({
      query: code => ({
        url: `auth/login/?code=${code}`,
        method: 'POST',
      }),
      invalidatesTags: (result, error, arg) => {
        console.log('auth/login', result, error, arg)
        return ['User']
      },
    }),
    getMe: build.query({
      query: () => 'auth/me',
      providesTags: result => {
        console.log('auth/me', result)
        return ['User']
      },
    }),
  }),
})

export const { useLoginMutation, useGetMeQuery } = api

login is called on component mount when the page is loaded from a callback like this:

const CallbackComponent = () => {
  const location = useLocation()
  const [login, { isUninitialized, isLoading, isError, data, error }] = useLoginMutation()

  useEffect(() => {
    if (isUninitialized) login(getCode(location))
  })
  ...
}

getMe is used in a component like this:

const Header = () => {
  const isAuthenticated = useIsAuthenticated()
  const {
    data: user,
    isError,
    error,
  } = useGetMeQuery(null, {
    skip: !isAuthenticated,
  })

  if (isError) return <span>{JSON.stringify(error)}</span>

  return (
    <nav className="header">
      {user ? <CharacterList characters={user.characters} /> : null}
      {!user || user.characters.length === 0 ? <Login /> : null}
    </nav>
  )
}
Meuse answered 22/9, 2021 at 8:1 Comment(0)
M
13

Turns out the issue was not in any of these places. I had not added the api middleware to my store.

export const store = configureStore({
  reducer: rootReducer,
  middleware: getDefaultMiddleware =>
    getDefaultMiddleware().concat(api.middleware),
})

docs: https://redux-toolkit.js.org/tutorials/rtk-query#add-the-service-to-your-store

Meuse answered 22/9, 2021 at 8:48 Comment(0)
I
0

I had an quite similar issue where the getMe request would throw an HTTP 401 response code when called without an valid session token. Turns out, that removing the 401 on server side fixed the issue.

However, this is not an optimal solution, so instead I figured out, the providesTags: ['example'] does provide the tag only on success. To also provide it on failure or some other tag use something like this:

providesTags:(result, error, id)=> (
  result
    ? ['example']
    : (error?.status === 401 ? ['UNAUTHORIZED'] : ['UNKNOWN_ERROR'])
)

Although you found your solution to the problem already, this might help someone else running into similar issues.

Inshrine answered 10/9, 2023 at 20:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.