Wisnu
Wisnu

Reputation: 337

Overcome endless looping when executing useQuery (ApolloClient) by defining a new client

I need to define "client" when running "useQuery", but I get endless looping.

I wrote the code as below:

const QueryKTP = gql`
  query {
    documents(transactionId:"${transactionId}", input: [
      {documentType:"KTP"}
    ]){
      documentResponses{
        documentType
        documentBase64
      }
      responseDescription
      responseCode
     message
    }
  }`

const anotherClient = new ApolloClient({
  uri: "https://my-url/online-service/graphql"
});

const { data, loading } = useQuery(QueryKTP, {client: anotherClient});

If I change the script above to be like below (remove new client), looping no longer occurs.

const { data, loading } = useQuery(QueryKTP);

What do I need to fix? Thank you

Upvotes: 4

Views: 8425

Answers (3)

Dospore
Dospore

Reputation: 11

In my case I had multiple different graphUri dependent on the network selection of my app. The issue for me was that I was using the example code ApolloWrapper as such,

const ApolloWrapper: (uri: string) => ApolloClient<any> | Error = (
  uri: string
) => {
  try {
    return new ApolloClient({
      link: link.concat(createHttpLink({ uri: uri })),
      cache: new InMemoryCache(),
    });
  } catch (err) {
    console.error("Failed to connect to client");
    return Error(err);
  }
};

and then using it as

const GraphProvider: ({ children }: GProps) => any = ({ children }: GProps) => {
  const client = Client.ApolloWrapper(config?.graphUri ?? "");
  return (
    <ApolloProvider client={client as ApolloClient<any>}>
      {children}
    </ApolloProvider>
  );
};

where of course the default uri here is '' which resolves to nothing.

With this config when it was trying to instantiate the httpLink it was obviously erroring. This was also the case for any other network issue like it couldnt resolve. I didn't notice the issue until adding some error checking to useQuery and found the loop.

The fix for me was as simple as memoising graphUri so it doesnt continuosly throw the error cause a rerender, throw the error cause a rerender etc. Replacing the wrapper as followed so that it only creates a new instance of the client when the uri changes. Am not sure if I missed a super simple solution in the Apollo docs but none of their stuff seemed to work.

const ApolloWrapper: (uri: string) => ApolloClient<any> | Error = (
  uri: string
) => {
  const client = useMemo(() => {
    try {
      return new ApolloClient({
        link: link.concat(createHttpLink({ uri: uri })),
        cache: new InMemoryCache(),
      });
    } catch (err) {
      console.error("Failed to connect to client");
      return Error(err);
    }
  }, [uri]);
  return client;
};

Upvotes: 1

Kamil&#39; Ocean
Kamil&#39; Ocean

Reputation: 616

Finally, I've figured out. I faced the same problem and I solved it by excluding new ApolloClient from render function.

Actually, I don't see render function from your code, but in my case, it was something like this:

Before

export default function MyComponent () {
  const anotherClient = new ApolloClient({
    uri: "https://my-url/online-service/graphql"
  });
  const { data, loading } = useQuery(QueryKTP, {client: anotherClient});
}

After

const anotherClient = new ApolloClient({
  uri: "https://my-url/online-service/graphql"
});
export default function MyComponent () {
  const { data, loading } = useQuery(QueryKTP, {client: anotherClient});
}

In my case, it helped. You should know, that in similar cases just look to new keyword. For example, guys often meet the same bug with an infinite loop, when they use new Date() in the render function

Upvotes: 4

Nadezhda Serafimova
Nadezhda Serafimova

Reputation: 802

I noticed that the client is not defined properly. Can you please try to initialize anotherClient as follows:

const anotherClient = new ApolloClient({
    link: new HttpLink({
        uri: 'https://my-url/online-service/graphql'
    })
});

Don't forget to import HttpLink, next to ApolloClient.

Upvotes: 0

Related Questions