Search code examples
rtk-query

RTK Query 'data' property contains previous calls data, when subsequent request with different arguments is an error


I have an endpoint configured as follows:

getResourcesWithFilter: build.query<Paged<{ resources: Array<Resource> }>, GetResourcesWithFilterApiArg>({
  query: ({ componentId, resourceType }) => ({
    url: `/resources`,
    params: { componentId, resourceType },
  }),
  transformResponse: (resp: GetResourcesWithFilterApiResponse) => ({
    page: resp._embedded.page,
    resources: resp._embedded.resources,
  }),
}),

In my component, I have the following:

export const ResourceList: React.FC<ResourceList> = ({ componentId, resourceType }) => {
  const [getResources, { isFetching, error, data }] = useLazyGetResourcesWithFilterQuery();

  React.useEffect(() => void getResources({ componentId, resourceType }), [getResources, componentId, resourceType]);

return (
    <>
      {data && (<DataTable data={data} />)}
      {error && (<>
                   <Error error={error} />
                   <a onClick={()=> void getResources({ componentId, resourceType })}>Try again</a>
                 </>
                )}
    </>
);
};       

When the endpoint fetches a 200 response, data is holding the correct response. If the componentId or resourceType changes and the effect runs and makes a subsequent request (with different arguments) which returns a 403 (bad request) for example, then error contains the correct error, however I would expect data === undefined , however, data contains the response from the previous request.

So what's happening is that after an error occurs for a subsequent request, the error is being displayed, but also the data from the previous request. Shouldn't data === undefined if there is an error?


Solution

  • No, this is intended behaviour. Oftentimes, if you have an error, you want to display the last valid data alongside the error and not have it go away - because at that point you have no way of getting it back if it's gone once.

    If you don't want that, you can always check for isError and just not render data. You should generally probably not just blindly render data if it's there, but also check the status flags isLoadig, isFetching, isError, isSuccess and isUninitiated and render your component according to that.