xzhu
xzhu

Reputation: 5755

How to refetch until certain value is returned from the server? (React-Apollo)

With React-Apollo, is it possible to refetch again until the fetched data has a certain value?

Say I have a component who keeps pinging the server until the server gives back a certain response.

graphql(gql`
  query {
    ping {
      response
    }
  }
`)(MyComponent)

The server either returns

ping: {
  response: "busy"
}

or

ping: {
  response: "OK"
}

I want this component to keep pinging the server every one second (polling) until the response is "OK". What is the easiest way to do it with Apollo?

Upvotes: 4

Views: 6044

Answers (3)

Paul Razvan Berg
Paul Razvan Berg

Reputation: 21378

You may want to use Subscriptions.

Example with Hooks:

useSubscription(
  gql`
    subscription {
      ping {
        response
      }
    }
  `
)

And of course, the useSubscription Hook accepts a second parameter for options, so you could set your arguments like this:

useSubscription(YOUR_SUBSCRIPTION, { variables: { foo: bar } })

Upvotes: 0

Tal Z
Tal Z

Reputation: 3210

Basically all you need to do is set up a query with an option pollInterval and when you get the wanted response call the stopPolling function that arrives on the data in the props function. And make sure the fetchPolicy is set to 'network-only' that is compatible with polling.

Read about options.pollInterval here, about options.fetchPolicy here and about the structure of the data prop here.

This code should work for you:

const PingQuery = gql`
  query {
    ping {
      response
    }
  }
`

graphql(PingQuery, {
    options: {
        fetchPolicy: 'network-only', // we don't want to get the response from the cache
        pollInterval: 1000 // in milliseconds,      
    },
    props: ({data: {loading, ping, stopPolling}) => {
        if (loading) {
            return // still loading, ping is undefined
        }
        if (ping.response === 'busy') {
            // still busy
            return
        }       
        // not busy.. stop polling and do something
        stopPolling()
    }
})(MyComponent)

Upvotes: 5

jkdowdle
jkdowdle

Reputation: 178

I may not have a perfect answer but I may have something to point you in the right direction.

The graphql() higher order component, as you are probably aware, takes a second parameter of options. You can specify things like a polling interval to continually repeat the query.

In this article, they explain how they were able to dynamically change this polling interval based on specific conditions.

https://dev-blog.apollodata.com/dynamic-graphql-polling-with-react-and-apollo-client-fb36e390d250

The example is using the recompose library, but I imagine you could do something similar like this.

import { graphql } from "react-apollo";
import gql from "graphql-tag";
import { compose, withState, lifecycle } from "recompose";

const QUERY = gql`
  query {
    ping {
      response
    }
  }
`;

const withPing = compose(
  withState("polling", "setPolling", true),
  graphql(
    QUERY,
    {
      options: props => {
        if (props.polling === true) {
          return {
            pollInterval: 1000 // Repeat query every 1 second
          };
        } else {
          return { } // or return nothing
        }
      }
    }
  ),
  lifecycle({
    componentWillReceiveProps({
      data: { loading, ping },
      polling,
      setPolling
    }) {
      if (loading) {
        return;
      }

      if (ping.response === 'OK') {
        return setPolling(false) // Stops polling
      } else if (ping.response === 'busy') {
        return setPolling(true) // Continues polling
      }
    }
  })
);

const ComponentWithPing = withPing(Component);

I don't know if this would acctually work, but it should be close.

Another avenue you could checkout is the data.refetch() method on the data response object.

https://www.apollographql.com/docs/react/basics/queries.html#graphql-query-data-refetch.

Best of luck!

You can read more about the options here https://www.apollographql.com/docs/react/basics/queries.html#graphql-query-options and specifically the pollInterval here https://www.apollographql.com/docs/react/basics/queries.html#graphql-config-options-pollInterval

Upvotes: 1

Related Questions