How to pass variable to graphql from method when onClick with button and get it's return data back?
Asked Answered
S

1

1

I need to pass asset_type; value to graphql when user click on a button. What is the proper way to do that because currently I'm getting this error:

GraphQL error: Illegal value for Message.Field .am.AssetRequest.asset_type of type string: object (proto3 field without field presence cannot be null)

This is what I have in my code:

import gql from 'graphql-tag';
import { graphql } from 'react-apollo';

  constructor(props) {
    super(props);
    this.state = {
      value: '',
    };

    this.handleChange = this.handleChange.bind(this);
  }

  handleChange(event) {
   this.setState({ value: event.target.value });
  }

  submit() {
   this.state.value
   this.props.haha(this.state.value) //this is where I'm stuck. I'm not sure how to send it to graphql props.
  }

  render() {
   <div>
    <Input value={this.state.value} onChange={this.handleChange} />
    <button onClick={() => { this.submit(); }} >
     <span>Run Query</span>
    </button>
   </div>
  // other html element
  }

const queryVariable = gql`
  query RootQuery($asset_type: String) {
    am {
      assets(asset_type: $asset_type) {
        data {
          uuid
          label
          asset_type
          description
        }
      }
    }
  }
`;

export default graphql(queryVariable, {
  props: ({ query }) => ({
    haha: (asset_type) => query({
      variables: { asset_type },
    })
  })
})(PlacementSearch)

I can get the data with graphiql though:

enter image description here

but I cannot send and get the return data back? Please help and thanks in advance

Stauffer answered 21/7, 2017 at 19:14 Comment(0)
I
3

The graphql takes care of running your query for you. Apollo will fetch the data from your server and make it available to your component once the request completes -- there is no need to somehow call the query in response to a user action.

Here's how to make this work with your query:

const queryOptions = {
  variables: {
    asset_type: 'r'
  }
}

export default graphql(queryVariable, {
  options: queryOptions
})(PlacementSearch)

With this configuration, the data part of your query will be available as props.data inside your component once the request completes (which means you will need to account for it initially coming back as null). So, for example, if you needed the label from the data returned by your query, you would just use props.data.label.

You can fine tune the props that the HOC passes to your component by providing an optional props property to your configuration object. For example, you could do:

const queryOptions = {
  variables: {
    asset_type: 'r'
  }
}

// ownProps below maps to the component's existing props if you want to
// use those in calculating derived props
const mapDataToProps = ({data, ownProps}) =>
  ({
      uuid: data.uuid
      label: data.label
      assetType: data.asset_type
      description: data.description
   })

export default graphql(queryVariable, {
  options: queryOptions
})(PlacementSearch)

With the configuration above, if I wanted to get the asset type, I would retrieve it from props.assetType.

There's a lot of other options you can configure. I highly recommend going back over the docs and paying special attention to how the configuration object is utilized in both queries and mutations.

EDIT: If you want to run the query again with a different set of variables, configure your HOC like this:

export default graphql(queryVariable, {
  // r can be whatever you want the default variable to be
  options: { variables: { asset_type: 'r' } }
})(PlacementSearch)

Then, in your handler:

submit() {
 this.props.data.refetch({ asset_type: this.state.value})
}

Again, to render the data from your query, you'll need to use this.props.data.

Inveterate answered 21/7, 2017 at 20:30 Comment(3)
I'm sorry if my question was not clear. I actually can get the query results if I hardcoded the value to graphql query. What I failed to do is sending variable from method when user click on a button. Which mean the variable is not hardcoded. I revised my question above and hopefully you can help me with this. I already go through the docs and I confused at button and method part. From my example above, I can get the user input variable in method but how do I send it to graphql? Thanks in advance.Stauffer
Please see the edit above. You'll always need some kind of default value hardcoded into the query to get your initial data, but you can change it by calling refetch. If you wanted the data to be empty until the user enters a value and presses the button, you should be able to just set the initial value for asset_type to an empty string.Inveterate
Thank you for the detailed explanation. It is really helpful.Stauffer

© 2022 - 2024 — McMap. All rights reserved.