I have the following call of useSWR
:
const { data: idpData } = useSWR<Foo[]>(
buildUrl((): string => `/[...]/idps`),
(url: string): Promise<Foo[]> =>
fetch(url, { headers: { Authorization: `Bearer ${accessToken}` } })
.then((res): Promise<PaginationWithContentDetails> => res.json())
.then((data): Foo[] => data.content),
);
The following is how the resulting data is used somewhere:
{idpData?.map(
(idp: Foo): ReactElement => (
<option key={idp.id} value={idp.id} disabled={!hasEmailValid}>
{idp.name}
</option>
),
)}
During tests I recognized that most of the times the array behind data.content
is returned, but sometimes the JSON object itself of the response is returned. In the latter case the above rendering fails, because I do have some data, but it's an object instead of an array, so the map
call isn't available.
idpData?.map is not a function
This is unexpected to me, my understanding of useSWR
is that it either returns undefined
/null
as data or, depending on the actual config, some given fallback data or formerly available data from earlier responses. I don't give any fallback data and even data of former results should always be arrays only from my understanding.
- https://swr.vercel.app/docs/advanced/understanding
- https://swr.vercel.app/docs/advanced/performance#dependency-collection
To me it looks like that sometimes the intermediate result of the first .then
is returned. But there is further processing coded and it would violate the signature to return arbitrary intermediate data. OTOH, if I get unexpected intermediate data, it's really only the JSON response body, never the response itself or some other unexpected stuff. So the first .then
seems to succeed always. Consequently, if I change my fetching code to always return the JSON only and handle the array access during the render code, things succeed:
{idpData?.content?.map(
So, which data is guaranteed to be returned by useSWR in case it's still loading or validating or fetching or ...? Can it really be intermediate data in case multiple processings happen on the response within the fetcher callback?
Thanks!