How to pass variable to graphql from method when o

2019-09-16 17:10发布

问题:

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:

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

回答1:

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.