Search code examples
reactjsapolloreact-apolloapollo-client

onCompleted handler not firing with Apollo Client Query


I'm having issues getting the onCompleted callback to fire when executing an Apollo Client query.

The query has no problems running, and it returns the results I would expect, but the onCompleted handler never fires. I have tried multiple things:

  • a) I have tried using HOC instead of the React component (see comment at end of gist)
  • b) I've tried invalidating the cache and setting fetchPolicy to 'network-only'
  • I've tried setting the handler to "async"

There is an Github open issue related to what I'm experiencing, however the people in this thread only experience the problem when loading from cache. I'm experiencing the callback not firing all the time. https://github.com/apollographql/react-apollo/issues/2177

Here is a trimmed example of my code:

import React from 'react';
import { graphql, Query } from 'react-apollo';
import { ProductQuery } from '../../graphql/Products.graphql';

class EditProductVisualsPage extends React.Component {
  constructor() {
    super();
  }

  render() {
    const { productId } = this.props;
    return (
      <Query
        query={ProductQuery} 
        variables={{ id: productId }}
        onCompleted={data => console.log("Hi World")}>
        {({ loading, data: { product } }) => (
          /* ... */ 
        )}
      </Query>
    );
  }
}

export default EditProductVisualsPage;

/*
export default graphql(ProductQuery, {
  options: props => ({
    variables: {
      id: props.productId,
    },
    fetchPolicy: "cache-and-network",
    onCompleted: function() {
      debugger;
    },
  }),
})(EditProductVisualsPage);
*/

At this point I'm completely stumped. Any help would be appreciated.

Library versions

  • react-apollo (2.1.4)
  • apollo-client (2.3.1)
  • react(16.3.32)

Solution

  • (Answering this question since it has received a large number of views).

    As of April, 2019, the onCompleted handler still remains broken. However, it can be worked around by utilizing the withApollo HOC. https://www.apollographql.com/docs/react/api/react-apollo#withApollo

    Here is a sample integration:

    import React from 'react';
    import { withApollo } from 'react-apollo';
    
    class Page extends React.Component {
      constructor(props) {
        super();
        this.state = {
          loading: true,
          data: {},
        };
        this.fetchData(props);
      }
    
      async fetchData(props) {
        const { client } = props;
        const result = await client.query({
          query: YOUR_QUERY_HERE, /* other options, e.g. variables: {} */     
        });
    
        this.setState({
          data: result.data,
          loading: false,
        });
      }
    
      render() {
        const { data, loading } = this.state;
        /* 
          ... manipulate data and loading from state in here ...
        */
      }
    }
    export default withApollo(Page);