This is the second exercise in the React Track of this Apollo Client Tutorial!
The goal of this exercise is to query information on your very own trainer node. We will use it to add a personal touch to the greeting to our pokedex:

We will learn how to query information from a GraphQL server with Apollo Client.
Move to the second exercise, install the dependencies and start the pokedex React app from your console
cd pokedex-react/exercise-02
yarn install # or npm install
yarn start # or npm start
The schema exposed by our GraphQL server includes the following models
type Trainer {
id: String!
name: String!
ownedPokemons: [Pokemon]
}
type Pokemon {
id: String!
url: String!
name: String!
trainer: Trainer
}
We can manage pokemon trainers that are related to multiple pokemons and are identified by both an id and a name. A pokemon has a url and a name and is related to its trainer.
Let's now build a GraphQL query together to get the information of your trainer node stored on the server and change the message displayed in src/components/Pokedex.js.
Queries offer a flexible way to state data requirements. With Apollo Client, we first define queries and then inject their response to the inner component. As far as the inner component is concerned, the data could be coming from anywhere, which means we have a good decoupling between data source and data consumer.
The GraphQL server for the Pokedex App is configured so that we can identify trainers by their name. To query the information of a trainer given his name, you can use the following query:
query TrainerQuery {
Trainer(name: "__NAME__") {
id
name
}
}
With Apollo, we need to denote queries like this by using the gql tag contained in the graphql-tag package.
const TrainerQuery = gql`
query TrainerQuery {
Trainer(name: "__NAME__") {
name
}
}
`
If you signed up with GitHub, we already inserted your name in this query.
But how do we access the query result in our Pokedex component? We can use graphql exposed from the react-apollo package to inject query results to React components via the data prop.
const PokedexWithData = graphql(TrainerQuery)(Pokedex)
Wrapping components like this with graphql injects a new data object to the props of the inner component. We can stress this by updating the propTypes of the Pokedex component:
static propTypes = {
data: React.PropTypes.shape({
loading: React.PropTypes.bool,
error: React.PropTypes.object,
Trainer: React.PropTypes.object,
}).isRequired,
}
The data object provides several things, in particular
data.loading signifies whether a query is currently being sent to the server and we are waiting for the query responsedata.error will contain detailed informationloading is false, we know that the query response arrived and all the fields from the query are available via data. In our case, this is a Trainer object with the id and name properties, available at data.TrainerSo let's now change the message to display the name of the trainer once loading is false and no error occurred:
COPY THIS SNIPPET
copy to src/component/Pokedex.js
render () { if (this.props.data.loading) { return (<div>Loading</div>) } if (this.props.data.error) { console.log(this.props.data.error) return (<div>An unexpected error occurred</div>) } return ( <div className='w-100 bg-light-gray min-vh-100'> <Title className='tc pa5'> Hey {this.props.data.Trainer.name}, there are 0 Pokemons in your pokedex </Title> </div> ) }
Now let's put the previous steps together and modify our Pokedex component in src/components/Pokedex.js. First, we need to include the new dependencies:
COPY THIS SNIPPET
copy to src/component/Pokedex.js
import { graphql } from 'react-apollo' import gql from 'graphql-tag'
We also include the data prop to the propTypes and use data.loading and data.Trainer as discussed above:
class Pokedex extends React.Component {
static propTypes = {
data: React.PropTypes.shape({
loading: React.PropTypes.bool,
error: React.PropTypes.object,
Trainer: React.PropTypes.object,
}).isRequired,
}
render () {
if (this.props.data.loading) {
return (<div>Loading</div>)
}
if (this.props.data.error) {
console.log(this.props.data.error)
return (<div>An unexpected error occurred</div>)
}
return (
<div className='w-100 bg-light-gray min-vh-100'>
<Title className='tc pa5'>
Hey {this.props.data.Trainer.name}, there are 0 Pokemons in your pokedex
</Title>
</div>
)
}
}
Finally, we are defining the TrainerQuery (insert your name!), connect it to our Pokedex component and finally export the new component:
COPY THIS SNIPPET
copy to src/component/Pokedex.js
const TrainerQuery = gql` query TrainerQuery { Trainer(name: "__NAME__") { name } } ` const PokedexWithData = graphql(TrainerQuery)(Pokedex) export default PokedexWithData
If you finished all the changes to src/components/Pokedex.js successfully, open http://localhost:3000 in your browser and you should see the updated greeting.
Nice, you executed your first GraphQL query with Apollo Client and used it to display your trainer name. In this exercise we learned a lot! Let's recap that:
gql tag from the graphql-tag packagegraphql from react-apollo using a query injects the data prop to the inner componentdata.loading becomes false, the data prop will contain the fields of the query. We can render a loading state as long as data.loading is true.