apollo-client: Query data and error are undefined
Intended outcome:
I’m using useQuery
to query and render some data. The loading
prop works as expected, the value is true
and then changes to false
. When loading is false, data
and error
are both undefined
.
I checked the network tab and the data is being received (I see the data
prop)
I also checked what’s going on with the Apollo chrome extension and I can see the data
I also was able to verify the correct result from the BE using the fetch
API
Actual outcome:
data
and error
props from useQuery
are undefined
.
How to reproduce the issue:
Here’s the component that uses useQuery
and fetch
const QUERY = gql`
query AccountStatus {
accountStatus {
__typename
missingCode
completed
reason
}
}
`
const MissingThings = () => {
const x = useQuery(QUERY)
const { loading, data, error } = x
console.log('--x', x)
useEffect(() => {
fetch(`${process.env.REACT_APP_GRAPHQL_URL}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization:
'Bearer <TOKEN>',
},
body: JSON.stringify({
variables: {},
query: `
query AccountStatus {
accountStatus {
__typename
missingCode
completed
reason
}
}
`,
}),
})
.then((result) => result.json())
.then((result) => console.log('--result', result))
.catch(console.error)
}, [])
if (loading) {
return null
}
if (error) {
console.log('--error', error)
return null
}
console.log('--data', data)
return <div>All good</div>
}
And this is the Apollo Client
const ApolloClientProvider = ({ children }: any) => {
const { auth, account } = useGlobalProvider()
const headers =
auth && account ? { Authorization: `Bearer ${auth?.token}` } : {}
console.log('--headers', headers)
console.log('--auth', auth)
const wsLink = new WebSocketLink({
uri: process.env.REACT_APP_GRAPHQL_WS_URL as string,
options: {
reconnect: true,
connectionParams: () => ({
headers,
}),
},
})
const httpLink = new HttpLink({ uri: process.env.REACT_APP_GRAPHQL_URL })
const authMiddleware = new ApolloLink((operation, forward) => {
// add the authorization to the headers
operation.setContext({
headers:
auth && account ? { Authorization: `Bearer ${auth?.token}` } : {},
})
return forward(operation)
})
const splitLink = split(
({ query }) => {
const definition = getMainDefinition(query)
return (
definition.kind === 'OperationDefinition' &&
definition.operation === 'subscription'
)
},
wsLink,
httpLink,
)
const logoutLink = onError((error) => {
console.log('APOLLO ERROR!', error)
if (
error.networkError?.message.includes('JWTExpired') ||
error.graphQLErrors?.some(
({ extensions, message }) =>
extensions?.code === 'invalid-jwt' || message.includes('JWTExpired'),
)
) {
navigate('/logout')
}
})
const client = new ApolloClient({
cache: new InMemoryCache(),
link: ApolloLink.from([logoutLink, authMiddleware, splitLink]),
})
return <ApolloProvider client={client}>{children}</ApolloProvider>
}
Versions System: OS: macOS 11.2.3 Binaries: Node: 14.8.0 - ~/n/bin/node npm: 6.14.7 - ~/n/bin/npm Browsers: Chrome: 90.0.4430.72 Safari: 14.0.3 npmPackages: @apollo/client: ^3.3.15 => 3.3.15
About this issue
- Original URL
- State: open
- Created 3 years ago
- Reactions: 35
- Comments: 45 (7 by maintainers)
Why is this closed?
I’m having the same bug of
data
beingundefined
but when backgrounding my app and foregrounding it. Verified via flipper that the data was actually coming in though. SettingfetchPolicy: network-only
didnt solve it for my case.This should be resolved in @apollo/client@latest - let us know if not.
I’ve tried every suggestion in this post and many other sources and most of the apollo client versions that people said worked and the problem is present 100% of the time. My schema and query are as simple as possible. The data shape matches perfectly. ** The correct data is clearly being returned during the fetch. ** I’ve tried everything possible. The client is getting good data back from the server. I tried the no-cache setting and the partial data setting and saw no improvement. The Loading feature seems to work fine, but I get the UNDEFINED error and UNDEFINED data at the end. I was never able to get Apollo to work and tried 4 or 5 fresh passes at all code from server to client, schema to model. It’s obviously something going sideways in the client at the final stage of handing the data to the caller. Regarding the cache, I can only say the setting had no effect and I would not have had cached data in all cases of the failure, which for me was 100%.
I’m seeing the same thing (@apollo/client 3.5. 10):
useQuery
returnsundefined
forerror
anddata
, though I can see thatloading
is true at some point.We both consume and provide the GraphQL API, so I have full ability to debug on both ends. The network response is exactly as we’d expect. Notably, there are no errors in the network response; the shape of the response is exactly as we’d expected, with the queried object nested under
data
.For now, we’ve downgraded back to 3.2.5 to resolve this.
@jasongaare
If you are both the provider and consumer of the GraphQL API, this issue is occurring because the field structure of the query and the response do not match, which is usually due to the backend omitting a null field entirely instead of returning
null
for a null field. Example:Otherwise, if you are only the consumer of the GraphQL API, you’re unfortunately out of other options until this issue is resolved.
@brainkim I believe you’re right. The
useQuery
hook is silently failing when the response doesn’t match the query exactly, but the response has a corresponding cache entry.It would be nice to produce some kind of console warning or emit an error when this happens to prevent future confusion. I can take a further look at this later tonight.
I continued testing and I found out that not using the cache works:
Any idea of how to debug the cache? I see that the data is cached but Apollo is having a hard time retrieving it (that’s my conclusion)
Running into this problem on
3.7.1
First query gives undefined for data and error. Response of 200 with expected data can be seen in the network.
Still encountering this problem.
Confirmed the same on version 3.80 and 3.8.1. Downgrading is also not an option for me.
Same issue for me on
3.6.9
I get the error on the first load of the query. Then if I reload the page, the error from the hook is undefined but I can still see it in the network 😞I’m a little shocked this is still a thing, it only worked on 3.3.7 for me, not even 3.5.10.
it seems I was able to solve the problem!
If your server responds with a status other than 200, then “data” becomes “undefined” Example:
data (client) = undefined
data (client) = data{message: “not authorized”}
I hope this helps someone, good luck!
I’ve also encountered this issue, and setting
fetchPolicy: network-only
is not fixing it.The oddest thing is that when I’m on a page where an object is queried for some fields, and then I open a component where the same object is queried for different fields, it is WORKING.
However, when I’m on a page that doesn’t contain any graphql query, and I open the same component that queries the object, the issue happens. In the network tab in dev tools the API actually returned the right data, but in the code where I did
await client.query
I got undefined.I’ve tried to add
ID
to each of the object and subobjects and pass infetchPolicy: no-cache
orfetchPolicy: network-only
, but nothing works.I’m not doing watchQuery so
returnPartialData
is not an option.The component is rendered by
ReactDOM.render
. I’ve checked appollo dev tool, and the data from this component is not appearing in the dev tool no matter the data shows correctly in UI or not (for both cases mentioned above). In the meanwhile, another graphql call in the page shows in the cache.Hello, I’m experiencing this same issue, however I am not mocking anything.
As @brainkim suggested above, adding
returnPartialData
allows myuseQuery
hook to work again and properly return data. However, I’m not keen on adding that to all my queries with caching involved?Is there somewhere in the cache setup where this can be addressed? Or what long term solution could I implement that doesn’t involve adding the
returnPartialData
option to all my useQuery hooks?@diracs-delta This is a beautiful example. I’m dropping everything to investigate.
I was able to reproduce this issue on a separate repository. See below @brainkim
https://github.com/diracs-delta/apollo-client-8063