Calling a graphQL query from within react client

2.4k Views Asked by At

I'm trying to return a list of all users transactions, but I can't seem to call the graphQL query correctly. I've defined the query at the bottom and I'm trying to call it in refreshData(). What am I missing?

  async refreshData() {
    const allTransactions = await graphql(getTransactionsQuery);
    console.log(allTransactions);
    this.setState({
      transactions: allTransactions
    });
  }

  render() {
    const transactionsFromState = this.state.transactions;
    const transactions = transactionsFromState.map((transaction) =>
      <li key={transaction.id}>{transaction}</li>
    );
    return (
      <div className="App">
        <button onClick={() => this.refreshData()}> Refresh Data </button>
        <ul>{ transactions }</ul>
      </div>
    );
  }
}

const getTransactionsQuery = gql`
  query getTransactions($id: ID!) {
    transactions(userId: $id){Transaction}
  }
`;

//change User ID use context.user.id
export default graphql(getTransactionsQuery)(App);
1

There are 1 best solutions below

0
On BEST ANSWER

Using the graphql Higher Order Component

The graphql function you're calling returns a higher order component that can be then used to wrap another React component. It does not return a promise that can be awaited like you're trying to do.

You are already utilizing it (more or less) correctly here:

export default graphql(getTransactionsQuery)(App)

When you wrap your component with the graphql HOC like this, your component receives a data prop that can then be used inside your component's render method. This negates the need to utilize component state to persist your query results. Your render method should look something like this:

render() {
  const { transactions } = this.props.data 
  const transactionItems = transactions
    ? transactions.map(t => <li key={t.id}>{t}</li>)
    : null
  return (
    <div className="App">
      <button onClick={() => this.refreshData()}> Refresh Data </button>
      <ul>{ transactionItems }</ul>
    </div>
  );
}

data.transactions will be initially undefined before the query is fetched, so it's important to be mindful of that inside your render function. You can also check data.loading to determine if the query is still in flight. Please check the Apollo docs (here) for more examples.

Fetching a query with variables

Your query utilizes variables, so those variables need to be sent along with it. You'll need to pass those into the graphql function as options like this:

export default graphql(getTransactionsQuery, { options: { variables: { id: 'youridhere' } } })(App)

Options is normally passed an object, but it can also be passed a function. This function takes props as an argument, so that you can derive your variables from props if needed. For example:

const options = props => ({ variables: { id: props.id } })
export default graphql(getTransactionsQuery, { options })(App)

Check here for more information.

Refetching data

Since Apollo does the heavy lifting for you, there's no need to have a button to fetch the data from your server. But should you need to refetch your data, you can do so through the data prop passed down to your component by calling props.data.refetch(). You can read more about refetch here.