Batching with useQuery react hooks getting back undefined

736 views Asked by At

I am currently working on a project which requires me to make multiple queries/mutations. I tried setting up my apollo client with BatchHttpLink and I can see the data I am requesting in the network tab in the browser. It is coming back at an array of objects instead of JSON.

But the issue is when I try to grab the data in my component data is undefined. I tried using HttpLink instead of BatchHttpLink and I can get the data back from the hook.

My suspicion is the shape of the object that comes back from the response is different, I tried looking into documentation but I can't find much about batching.

Currently using "@apollo/client@^3.0.2"

Here's my client set up.

import { ApolloClient, InMemoryCache, ApolloLink, from } from '@apollo/client'
import { BatchHttpLink } from '@apollo/client/link/batch-http'
import { onError } from '@apollo/client/link/error'

const BASE_URL = 'http://localhost:4000'
const httpLink = new BatchHttpLink({
  uri: BASE_URL,
  credentials: 'include',
})
const csrfMiddleware = new ApolloLink((operation, forward) => {
  operation.setContext(({ headers = {} }) => ({
    headers: {
      ...headers,
      'X-CSRF-Token': getCSRFToken(),
    },
  }))
  return forward(operation)
})
const errorMiddleware = onError(({ networkError }) => {
  if (networkError && 'statusCode' in networkError && networkError.statusCode === 401) {
    window.location.assign('/accounts/login')
  }
})
const client = new ApolloClient({
  link: from([errorMiddleware, csrfMiddleware, httpLink]),
  cache: new InMemoryCache(),
})

This is the react hook I'm trying to console log.

const {data} = useQuery(GET_USER_PERMISSIONS_AND_PREFERENCES)
2

There are 2 answers

0
FFF On

I have been having a similar issue, and have so far only been able to solve it by breaking batching and converting to a normal HttpLink

0
Kenneth Zhu On

Figured it out. You need to add another middleware to return the data that the useQuery hook can recognize. The data that comes back in the batch call is an array of objects shaped

{ 
  payload: {
    data: { ... }
  }
}

So something like this did the trick for me

const batchParseMiddleware = new ApolloLink((operation, forward) => {
  return forward(operation).map((data: any) => data.payload)
})