0

I am trying to use a form input in react to filter my mongodb database with graphql and apollo. I have the backend set up and working. I have the front end mostly working except I can't access my data in an apollo query. Not sure what I am missing so not sure the exact question to ask. I am just doing a search or query not a mutation. I have 3 components in my React app and I am using styled-components. I just want to capture the form input data and store it in the apollo query for use. I want to call <h1>{data.herb.name}</h1> and get the data object from my apollo server.

I know this is a full stack question so if you can't help maybe you can give me suggestions on how to better ask this in smaller chunks. Thanks.

App.js

import React, { Component } from 'react'
import ApolloClient from 'apollo-boost'
import { ApolloProvider } from 'react-apollo'
import { BrowserRouter as Router, Route, Switch } from 'react-route-dom'

import Home from './components/Home'
import Herb from './components/Herb'

const client = new ApolloClient({
 uri: 'http://localhost:4000/graphql',
})

export default class App extends Component {
 render() {
   return (
    <ApolloProvider client={client}>
     <Router>
      <Switch>
        <Route exact path="/" component={Home} />
        <Route path="/:herbId" component={Herb} />
      </Switch>
     </Router>
    </ApolloProvider>
  )
 }
}

Home.js

import React, { Component } from 'react'
import styled from 'styled-components'

import SearchInput from './Search'
import Herb from './Herb'
import bgImage from '../Elements/images/measure_colorized.jpg'

const HomeContainer = styled.div`
  width: 100vw;
  height: 100vh;
  background: url(${bgImage});
  background-size: cover;
  background-repeat: no-repeat;
`

const Title = styled.h1`
  font-size: 6rem;
  color: #fff;
`

export default class Home extends Component {
  state = { name: '' }

  handleInput = e => {
    const formData = {}
    formData[e.target.name] = e.target.value
    this.setState({ ...formData })
  }

  render() {
    const { name } = this.state
    return (
      <HomeContainer>
        <header>
          <Title>Measure App</Title>
        </header>
        <SearchInput name={name} onChangeValue={this.handleInput} />
        <Herb name={name} />
      </HomeContainer>
    )
  }
}

Search.js

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

const SearchInput = styled.input`
  background: rgba(0, 0, 0, 0.6);
  width: 30vw;
  padding: 1rem;
  font-size: 1.6rem;
  color: white;
  border: none;
`

const SubmitBTN = styled.button`
  padding: 1rem;
  font-size: 1.6rem;
  border: none;
  background: #7ff2ca;
`

export default class Search extends Component {
  handleSubmit = e => {
    e.preventDefault()
  }

  render() {
    const { name, onChangeValue } = this.props
    return (
      <div>
        <Query query={GET_HERB_QUERY} variables={{ name }}>
          {(data, loading, error) => {
            if (loading) return 'Loading...'
            if (error) return `Error: ${error.message}`
            console.log(data)
            return (
              <Fragment>
                <SearchInput
                  name="name"
                  type="text"
                  placeholder="search"
                  value={name}
                  onChange={onChangeValue}
                />
                <SubmitBTN onClick={this.handleSubmit}>convert</SubmitBTN>
              </Fragment>
            )
          }}
        </Query>
      </div>
    )
  }
}

//writing query to fetch herb that matches search result
const GET_HERB_QUERY = gql`
  query searchHerbs($name: String) {
    herb(name: $name) {
      name
      description
      imageURL
    }
  }
`
1
  • 1
    Query component is used to 'fetch at start' - you need manually query firing Commented Sep 7, 2018 at 21:23

1 Answer 1

1

As explained in the comment, when you wrap your component with a query, the query will be triggered when your component renders.

You can manually fire the query and manage data as you wish. And you can also use the refetch method using the wrapper to trigger the query again with different variables.

Sign up to request clarification or add additional context in comments.

2 Comments

Is this the best or only way to handle inputs and button clicks in apollo? Seems a little like a hack. The docs mention to use Query if possible and this way is quite verbose.
Well, it's the way to refetch a query that is already plugged. I also think Apollo is quite verbose. But it compensate in the long run because all it adds, type checking, cache and other nice stuff. And you can always create your helper functions to make api cleaner on what you want. I view Apollo as a more generic tool/api that I need to add a layer over it specific to my needs.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.