Apollo GraphQL React - how to query on click?
Asked Answered
G

2

77

In the Apollo React docs http://dev.apollodata.com/react/queries.html#basics there are examples of fetching automatically when the component is shown, but I'd like to run a query when a button is clicked. I see an example to "re"fetch a query when a button is clicked, but I don't want it to query initially. I see there is a way to call mutations, but how do you call queries?

Greatuncle answered 2/10, 2016 at 7:34 Comment(1)
any ideas on this one? #49238990Jordan
B
76

You can do it by passing a reference to Apollo Client using the withApollo higher-order-component, as documented here: https://www.apollographql.com/docs/react/api/react-apollo.html#withApollo

Then, you can call client.query on the passed in object, like so:

class MyComponent extends React.Component {
  runQuery() {
    this.props.client.query({
      query: gql`...`,
      variables: { ... },
    });
  }

  render() { ... }
}

withApollo(MyComponent);

Out of curiosity, what's the goal of running a query on a click event? Perhaps there is a better way to accomplish the underlying goal.

Biflagellate answered 2/10, 2016 at 8:38 Comment(13)
i wanted to use this for a search barGreatuncle
Im finding if I use this on a component which has the gql HOC on a parent, it triggers the parents componentWillReceiveProps. No idea why. Is there a better way? perhaps redux.Primalia
This does not update the props? Why? How can I update props after the result comes in successfully?Deste
you can define an updateQuery function or updateQueries object in order to update the existing propsAhola
Why can be that shows this error: Error: Network error: Could not find query inside query map.?Backsaw
Are you using some persisted queries library?Biflagellate
@Biflagellate Yes, I have disabled persisted queries and I can use it. Thanks.Backsaw
@Ahola seems like updateQuery is not in client.query api, how we can archive that ?Tamie
Sounds like this should be a new question - I'm not quite sure what you're trying to do. You might be able to use client.writeQuery though: dev.apollodata.com/core/apollo-client-api.html#ApolloClient\.writeQueryBiflagellate
Shouldn't you just fire the submit event and pass the input as props to another component which utilizes them in a query?Decasyllabic
is there a way to get fetchMore() from this.props.client.query like what graphql() has under props.data.fetchMore()?Whoops
any ideas on this one? #49238990Jordan
In apollo 2.1 you can user <ApolloConsumer /> component apollographql.com/docs/react/api/…... Also this ---> apollographql.com/docs/react/essentials/…Inconstant
B
27

As of version 3.0, you can do this in two ways now.

client.query

The first way is to call ApolloClient's query method. This returns a Promise that will resolve to the query's result. You can get a reference to the client by using the withApollo HOC:

class MyComponent extends React.Component {
  handleClick() {
    const { data } = await this.props.client.query({
      query: gql`...`,
      variables: { ... },
    })
    ...
  }
  ...
}

withApollo(MyComponent)

Alternatively, you can also use ApolloConsumer to get the client:

const MyComponent = () => (
  <ApolloConsumer>
    {client => {
      ...
    }
  </ApolloConsumer>
)

or the useApolloClient hook:

const MyComponent = () => {
  const client = useApolloClient()
  ...
}

useLazyQuery

The second way is to use the useLazyQuery hook:

const MyComponent = () => {
  const [runQuery, { called, loading, data }] = useLazyQuery(gql`...`)
  const handleClick = () => runQuery({ variables: { ... } })
  ...
}
Brom answered 11/9, 2019 at 11:6 Comment(4)
Hooks are headache when you need handle subscriptions. Potential of making mistakes and open too many subscription channels on the server is too high! useMemo will help but subscribeToMore is so dangerous :)))Harbourage
useLazyQuery is just what we need for immediate load. Thanks.Nonbeliever
I have to use useApolloClient because I have a list of posts and each row of the list has an edit button. I want to get post data by its id and show data in a modal when I click on edit button. I tested useLazyQuery it doesn't get a post data again. I mean For the second and third time, I can not do this without refresh the page.Treen
@FullOfStack you should add argument fetchPolicy: 'network-only' in your useLazyQueryFranklin

© 2022 - 2024 — McMap. All rights reserved.