This was what we achieved in part 1 of the tutorial.
We will be requesting data from the Random User Generator's API.
To do that, we would need to install the gatsby-source-apiserver plugin and set the configuration options in a gatsby-config.js file.
$ npm install --save gatsby-source-apiserver
$ touch gatsby-config.js
Add the following code to gatsby-config.js.
module.exports = {
plugins: [{
resolve: 'gatsby-source-apiserver',
options: {
url: 'https://randomuser.me/api/',
method: 'get',
headers: {
'Content-Type': 'application/json'
},
typePrefix: 'internal__',
name: `posts`,
params: {
results: 10
},
verboseOutput: true,
}
}],
}
Let's go through the various options.
You can view the full option configurations from the plugin page.
What is gatsby-config.js used for?
The gatsby-config.js file stores plugin configurations and/or common pieces of data for code reuse throughout a GatsbyJS site.
See the GatsbyJS official documentation for details.
$ npm run develop
As mentioned earlier, GatsbyJS leverages on GraphQL to build its data layer for query extraction and execution.
The graphical interactive in-browser IDE; GraphiQL; allows developers to easily explore and structure their queries.
To access the IDE, visit http://localhost:8000/___graphql from your browser.
The IDE provides two helpful keyboard shortcuts. CTRL+Space for autocompletion and CTRL+Enter to run the query.
Let's try a simple query. Type the following in the GraphiQL IDE.
query {
}
GraphQL intelligently built the data schema by making connections to all internal__posts nodes.
Let's expand the query. We need the user's Name, Gender, Email, Contact No., Profile image and Address details.
With our structure ready, we can start to build the home page.
Open index.js and insert the following code.
import React from "react"
import { graphql } from "gatsby"
export const query = graphql`
query {
allInternalPosts {
edges {
node {
id
results {
name {
title
first
last
}
gender
email
phone
cell
nat
picture {
large
medium
thumbnail
}
location {
street
city
state
}
}
}
}
}
}
`
export default ({ data }) => {
return (
<div>
{data.allInternalPosts.edges.map(({ node }, ...index) => (
<div key={index}>
{node.results && node.results.map((data, ...index) => (
<div key={index}>
<ul>
<li>{data.name.title} {data.name.first} {data.name.last}</li>
<li>{data.gender}</li>
<li>{data.email}</li>
<li>{data.phone}</li>
<li><img src={data.picture.thumbnail} alt={`${data.name.title} ${data.name.first} ${data.name.last}`} /></li>
</ul>
</div>
))}
</div>
))}
</div>
)
}
Save your file to see the populated data in the browser.
With HMR or Hot Module Replacement support in GatsbyJS, the browser refreshes and loads new data everytime we save our changes.
We used GraphQL to pull data into our home page component.
We then used the JavaScript map() method to loop through the array and display the results on the page.
What is HMR?
Hot Module Replacement (HMR) exchanges, adds, or removes modules while an application is running, without a full reload. This can significantly speed up development in a few ways:
https://webpack.js.org/concepts/hot-module-replacement/
Add a file inside src/pages and name it details.js.
$ touch src/pages/index.js
Paste the following code in details.js.
import React from "react"
import { Link } from "gatsby"
export default ({ location }) => {
const value = location.state.data
return (
<div>
<img src={value.picture.large} alt={`${value.name.title} ${value.name.first} ${value.name.last}`} />
<div>
<h5>{value.name.title} {value.name.first} {value.name.last}</h5>
<ul>
<li><strong>Gender:</strong> {value.gender}</li>
<li><strong>Email:</strong> {value.email}</li>
<li><strong>Address:</strong> {value.location.street}, {value.location.city}, {value.location.state}</li>
</ul>
</div>
<div>
<Link to="/">Back to Home</Link>
</div>
</div>
)
}
Add a link to the details page in index.js.
import React from "react"
import { graphql, Link } from "gatsby"
...img src={data.picture.thumbnail} alt={`${data.name.title} ${data.name.first} ${data.name.last}`} /></li>
<li><Link
to={`/details/`}
state={{data}}
>View Details</Link></li>
...
We include a GatsbyJS Link component in both index.js and details.js to link internal pages within our site.
To pass user data from the source page to the linked page, we passed data prop in the location state.
Thereafter, we can use the passed data as a nested object structure with the location prop in details.js.
Our pages are getting chunky. Let's refactor the code.
Create a new src/components folder and add a new file profile.js inside it.
$ mkdir ./src/components && touch ./src/components/profile.js
Add the following code to profile.js.
import React from "react"
import { Link } from "gatsby"
export default ({props}, index) => {
return (
<ul>
<li>{props.name.title} {props.name.first} {props.name.last}</li>
<li>{props.gender}</li>
<li>{props.email}</li>
<li>{props.phone}</li>
<li><img src={props.picture.thumbnail} alt={`${props.name.title} ${props.name.first} ${props.name.last}`} /></li>
<li>
<Link
to={`/details/`}
state={{props}}
>View Details
</Link>
</li>
</ul>
)
}
Edit index.js with the following.
...
import { graphql } from "gatsby"
import Profile from "../components/profile.js"
...
export default ({ data }) => {
return (
<div>
{data.allInternalPosts.edges.map(({ node }, ...index) => (
<div key={index}>
{node.results && node.results.map((data, ...index) => (
<div key={index}>
<Profile props={data} />
</div>
))}
</div>
))}
</div>
)
}
Change the value of location.state.data to location.state.props in details.js.
...
export default ({ location }) => {
const value = location.state.props
return (
...
Our page still works. The main difference is that we split the code into smaller manageable components.
The application is still missing an important feature. Search.
In part 3, we will integrate a search feature to our application using JS Search and Axios.