InfernoJS meets Apollo in a functional way [part 2]
A few days have passed since my first post about the functional interagation of InfernoJS and Apollo. Today I’ve updated the inferno-apollo-demo with a plain routing config and props based graphQL querying.
What’s new
- added infero-router (with a plain route configuration)
- added ‘FilmDetail’ component
- updated dependencies
Inferno-Router with plain route configuration
The inferno-router is a port of the react-router and provides almost the same API. The JSX implementation of the Router could look something like this:
<Router history={browserHistory}>
<Route path="/" component={App}>
<IndexRoute component={Home} />
<Route path="films" component={Films} />
<Route path="/*" component={NoMatch} />
</Route>
</Router>
But in the demo app we use a functional way without the JSX wrapping.
So that’s a solution useable in react already called plain route:
const route = [
{
path : '/',
component : App,
indexRoute : {
component : Home
},
childRoutes : [
{
path : 'films',
component : Films
},
{
path : '/*',
component : NoMatch
}
]
}
];
Doesn’t look to complicated, right? Just a plain object tree reflection of the JSX solution. What you prefer is totally up to you. Both solutions transpile to a createElement(component, props)
function call at the end. Currently a PR is open to bring this functionality also to the inferno-router.
Film Detail component
This component is new and handles the detail view of a film. Since the other components are already described in part 1, let’s dive right into its implementation.
The detail query
const query = gql`
query FilmDetail($filmId: ID!) {
node(id: $filmId) {
type: __typename
... on Film {
id
title
episodeID
director
releaseDate
}
}
}
`;
Let’s go line by line through this query.
query FilmDetail($filmId: ID!) {
First we define the query and call it FilmDetail
. We pass this query a parameter like we would do on normal functions. We tell graphQL, that we want to use a variable called $filmID
of type ID
.
node(id: $filmId) {
On the next line we querying the graphQL node called node
by using the before defined variable $filmId
.
type: __typename
__typename
is a selector option in graphQL. It tells us, what type the fetched node
implements. In our case we know that we just pass IDs of film nodes, but if we don’t know it and want to change something on the front end, this is how you could get the type. type
is just a name alias in this example. So we could get the type by using props.data.type
instead of props.data.__typename
.
... on Film {
id
title
episodeID
director
releaseDate
}
With ... on Film
we tell graphQL on which fields we’re interested if the node is of type Film
. If the node is not of type Film
, all we get is the type
. The other fields wont exist on props.data
!
Define the query variable
GraphQL knows, that we will pass a variable called $filmId
before the request will be sent. But where do we define the variable and its value?
In our example app it is defined in the compose section of the FilmDetail component and looks like this:
graphql(query, {
options : (props) => ({
variables : {
filmId : props.params.id,
}
})
}),
The graphQL
function gets as first param our query. The second param is a object where we can define some settings for this request. In our case we just use the options
key.
Since we want to use our component props, the value of the options
key has to be a function. This function will be called, when the FilmDetail
component receives its props. The return value of the options
function is a object containing all variables we’d like to pass to graphQL. In our case it’s just one key named filmId
(please make sure, that you don’t use $
here) with the value contained in props.params.id
. This id is provided by the inferno-router.
Okay and that’s it. Happy hacking and exploring!
If your new to inferno and/or to graphQL, please check out the first part of this story.
Hope you enjoyed reading this and hopefully trying some queries on your own. If you have any questions leave me a note or ping me on @roman_zanettin also on twitter.