Reputation: 5755
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
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
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
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