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?
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.