mjuopperi
mjuopperi

Reputation: 971

Redux RTK query invalidatesTags not called after mutation

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>
  )
}

Upvotes: 7

Views: 4641

Answers (2)

Tim Nikischin
Tim Nikischin

Reputation: 817

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.

Upvotes: 0

mjuopperi
mjuopperi

Reputation: 971

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

Upvotes: 13

Related Questions