Coherent
Coherent

Reputation: 2113

How to pass graphQL query variable into a decorated react component

Does anyone know how what the proper way to add a query variable to apollo is from react? I can get the following code to work if I manually add the book name string instead of passing in the $name query variable, but as soon as I add it and try and pass the name variable in through an options in the propTypes, the Invariant Violation: The operation 'data' wrapping 'BookPage' is expecting a variable: 'name' but it was not found in the props passed to 'Apollo(BookPage)'

I pulled the syntax for the decorator directly from the reactQL package so I know it has a little more syntactic sugar than other examples but it should still be valid for a query right?

const query = gql`
  query ($name: String!){
    bookByName(name: $name) {
      id
    }
}
`;

@graphql(query)
class BookPage extends React.PureComponent {
  static propTypes = {
    options: (props) => { return { variables: { name: "Quantum Mechanics"}}},
    data: mergeData({
      book:
        PropTypes.shape({
          id: PropTypes.string.isRequired,
        }),
    }),
  }

  render() {
    const { data } = this.props;
    if (data.loading) {
      return <p>Loading</p>
    }
    const { bookByName } = data;
    const book = bookByName;

    return (
      <p>book.id</p>
    );
  }
}

export default BookPage;

Upvotes: 3

Views: 2903

Answers (1)

Locco0_0
Locco0_0

Reputation: 3500

The @graphql decorator has a second parameter where you define options for the Query or Mutation.

Similar to the options definition in the config.

So in your case it could look like:

const query = gql`
  query ($name: String!){
    bookByName(name: $name) {
      id
    }
}
`;

@graphql(query, {
  options: (ownProps) => ({
    variables: {
      name: ownProps.bookName // ownProps are the props that are added from the parent component
    },
  })})
class BookPage extends React.PureComponent {
  static propTypes = {
    bookName: PropTypes.string.isRequired,
    data: mergeData({
      book:
        PropTypes.shape({
          id: PropTypes.string.isRequired,
        }),
    }),
  }

  render() {
    const { data } = this.props;
    if (data.loading) {
      return <p>Loading</p>
    }
    const { bookByName } = data;
    const book = bookByName;

    return (
      <p>book.id</p>
    );
  }
}

export default BookPage;

Upvotes: 4

Related Questions