Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass variable from input to GraphQL search call

I am in the process of learning graphql and react-apollo. I have set up a search query in my code. I am unsure how to pass a variable from my code (i.e. this.state.search) to my grapnql call.

I have looked at many answers including this one, but it seems a bit different.

The docs also don't seem to give any guidance on how to use state as the variable.

My code is below.

Can anyone advise how to connect both of these?

import React, { Component} from 'react'
import { graphql } from 'react-apollo'
import gql from 'graphql-tag'

class Search extends Component {

  constructor(props) {
    super(props)
    this.state = {
      search: ''
    }
  }

  updateSearch = (e) => {
    this.setState({
      search: e.target.value
    })
  }

  submitSearch = (e) => {
    e.preventDefault()
    console.log(this.state)
  }

  render() {

    const { search } = this.state;

    return (
      <form onSubmit={ this.submitSearch }>
        <input 
          type='text'
          onChange={ this.updateSearch }
          value={ search }
          placeholder='Search'    
        />
      </form>
    )
  }
}


export default graphql(gql`
{
  search(query: "Manchester", type: TEAM) {
    name
  }
}`)(Search)
like image 257
peter flanagan Avatar asked Mar 12 '18 15:03

peter flanagan


People also ask

How do you pass a query in GraphQL?

GraphQL queries allow us to pass in arguments into query fields and nested query objects. You can pass arguments to every field and every nested object in your query to further deepen your request and make multiple fetches.

How do you implement search functionality in GraphQL?

Implementing Search Functionality on the Client To implement search via the client, we'll be using the data. fetchMore function from React Apollo. We'll pass a function to our component, onSearch , that will pass in the search query. onSearch will call props.

How do I use variables in GraphQL?

Variables simplify GraphQL queries and mutations by letting you pass data separately. A GraphQL request can be split into two sections: one for the query or mutation, and another for variables. Variables can be declared after the query or mutation and are passed like arguments to a function and begin with $.

How to accept dynamic values in GraphQL query?

This query requires the name of the repository that we are querying for and the name of the owner as well. Now the same query above can be written to accept dynamic values using the concept of variables in GraphQL. The client could reuse the same query to pass different arguments (name and owner).

How do I reuse a query in GraphQL?

In GraphQL, you can use variables to reuse the same query/mutations written by the client, with different arguments. To get started, let’s look at a query that accepts some arguments as parameters. In this query, we are going to query for a repository name and owner id.

What happens when a variable is passed to a query?

If any variables are passed as part of the variables dictionary, they will override the defaults. Reuse: The reason variables exist in GraphQL, is to allow reuse of the same queries and mutations for different sets of parameters and values. Clients can just pass a different set of variables instead of constructing a new query or mutation


1 Answers

You'll want to split this up into at least two components. One that holds the state of what the user searched, then another that actually does the querying by getting a prop. Additionally you can have the apollo higher order component skip the query if the form was submitted without entering something.

import React, {Component} from 'react'
import {graphql} from 'react-apollo'
import gql from 'graphql-tag'

class Results extends Component {
   render() {
    // apollo provides results under the data prop
    const {data} = this.props;
    return <h1>{data.search.namej}</h1>
   }
}

const ResultsWithQuery = graphql(gql`
query FindTeam($query: String!) {
    search(query: $query, type: TEAM) {
        name
    }
}
`, {skip: (ownProps) => !ownProps.query})(Results);

export class Search extends Component {

constructor(props) {
    super(props)
    this.state = {
        search: ''
    }
}

updateSearch = (e) => {
    this.setState({
        search: e.target.value
    })
}

submitSearch = (e) => {
    e.preventDefault()
    console.log(this.state)
}

render() {

    const {search} = this.state;

    return (
        <div>

        <form onSubmit={this.submitSearch}>
            <input
                type='text'
                onChange={this.updateSearch}
                value={search}
                placeholder='Search'
            />
            <ResultsWithQuery query={search} />
        </form>
        </div>

    )
}
}

* UPDATE * Now that [email protected] has been released there is an alternative way using render props.

https://www.apollographql.com/docs/react/essentials/get-started.html#request

This simplifies the number of components you need in this case.

import React, { Component} from 'react'
import { Query } from 'react-apollo'
import gql from 'graphql-tag'

const SearchQuery = gql`
query FindTeam($query: String!) {
  search(query: $query, type: TEAM) {
    name
  }
}
`;

export default class Search extends Component {

constructor(props) {
    super(props)
    this.state = {
        search: ''
    }
}

updateSearch = (e) => {
    this.setState({
        search: e.target.value
    })
}

submitSearch = (e) => {
    e.preventDefault()
    console.log(this.state)
}

render() {

    const { search } = this.state;

    return (
        <form onSubmit={ this.submitSearch }>
            <input
                type='text'
                onChange={ this.updateSearch }
                value={ search }
                placeholder='Search'
            />
            <Query query={SearchQuery} skip={!search} variables={{query: search}}>
               {({loading, error, data}) => {
                    if (loading) return null;
                    if (error) throw err;
                   return <h1>{data.search.namej}</h1>
                }}
            </Query>
        </form>
    )
}
}
like image 129
Nathanael Smith Avatar answered Oct 19 '22 12:10

Nathanael Smith