< Previous: Fetching Ajax Data from GitHub using SuperAgent | Next: Time for a Task: Reading from Three Feeds > |
GitHub's JSON is full of interesting data we could show, so the first thing to do is have a look through it for particularly meaningful things. Modify your componentWillMount()
method so that it has this line just before the call to setState()
:
src/pages/Detail.js
console.dir(response.body);
Once that's done, save and reload the page in your browser, then look in the error log window and you should see "Array [30]" or similar in there. Using console.dir()
prints a navigable tree in the log, so you should be able to click an arrow next to "Array [30]" to see the individual objects inside it.
Each of the objects you see is an individual React code commit to GitHub, and each one should have another arrow next to it that you can fold out to see what's inside the commit. Things that stand out to me as being interesting are:
Warning: GitHub can change its API in the future, so these fields may not apply when you try it yourself. So, look through the result of console.dir()
and find something that interests you!
What we're going to do is print the name of the author in bold, then the full text of their commit. I'm going to make the commit text clickable using the GitHub URL for the commit.
In the perfect world, the JSX to make this happen is simple:
(<p key={index}>
<strong>{commit.author.login}</strong>:
<a href={commit.html_url}>{commit.commit.message}</a>.
</p>)
(Note 1: we need to use commit.commit.message
and not commit.message
because the message is inside an object that is itself called commit
. Note 2: it is stylistically preferred to add parentheses around JSX when it contains multiple lines.)
Sadly, if you use that code there's a chance you'll get an error. It's not guaranteed because obviously the list of commits you see depends on what commits have happened recently, but sometimes there is nothing in the author field – that gets set to null. So, trying to use commit.author.login
will fail because commit.author
doesn't exist.
There are a few ways to solve this. First, we could clean the data when it arrived in from the Ajax call: if a commit doesn't have an author just skip over it. Second, we could use a ternary expression to check for the existence of an author and provide a meaningful default if it doesn't exist, like this:
(<p key={index}>
<strong>{commit.author ? commit.author.login : 'Anonymous'}</strong>:
<a href={commit.html_url}>{commit.commit.message}</a>.
</p>)
That's a simple enough solution, but what happens if the commit HTML URL is missing, or the commit message is missing? You end up with ternary expressions scattered everywhere, which is ugly.
Instead, there is a third option: calculate any fields up front. This means using slightly different syntax: we need open and close braces with map()
, and our code needs to return a value using the return
keyword.
Using this technique, here's the new render()
method for the Detail component:
src/pages/Detail.js
render() {
return (<div>
{this.state.commits.map((commit, index) => {
const author = commit.author ? commit.author.login : 'Anonymous';
return (<p key={index}>
<strong>{author}</strong>:
<a href={commit.html_url}>{commit.commit.message}</a>.
</p>);
})}
</div>);
}
This revised code creates a new author
constant that is set to either the name of the author or Anonymous depending on whether an author was provided. It still uses a ternary expression, but it separates the calculation of the values from the rendering, which makes it easier to read.
Buy the book for $10
Get the complete, unabridged Hacking with React e-book and take your learning to the next level - includes a 45-day no questions asked money back guarantee!
If this was helpful, please take a moment to tell others about Hacking with React by tweeting about it!
< Previous: Fetching Ajax Data from GitHub using SuperAgent | Next: Time for a Task: Reading from Three Feeds > |
Copyright ©2016 Paul Hudson. Follow me: @twostraws.