Welcome to the second task in this series. The first was building a portfolio, and I wrote about it here.
About this task
I created a static web page that fetches a GitHub profile using the GitHub REST API. You enter a name and click on the Search button. Then it returns the GitHub username, their display picture(avatar), number of followers and repos, and their top four repos based on the number of stars.
It is a full-stack project built using ReactJS, NodeJS, and Express. I guess I could have done without the ReactJS and just used plain HTML, CSS, and JS. But I have been hearing about it a lot, and I wanted to see how it works. No knowledge is a waste, amairite?
Random stuff I learned
The relatively interesting concepts I learned while putting this web page together have nothing to do with the backend aspect. But I'll mention two here:
- Reusable components: This is just as the name suggests - reusing components in various parts of an application. For example, one of the components created for this webpage is a Button component. If I had to add more features to this page and several of these features require a button, I would not need to rewrite a button tag for each one. I would call the already defined component and add a different style if necessary. I believe this follows the DRY (Do not Repeat Yourself) principle in programming.
It helps save time by ensuring less code is written, development is faster, the codebase is simpler, and maintenance is stress-free. - LogRocket
- Rate limit: This prevents an application from being bombarded with requests and then crashing as a result. GitHub's API only allows about 60 requests per hour (per user). This only increases to about 5000 per hour with authentication using personal access tokens or OAuth tokens.
Shared services need to protect themselves from excessive use—whether intended or unintended—to maintain service availability. - Google Cloud Architecture Center
Challenge(s)
My number one challenge was styling and CSS, as usual. Thankfully I had some help from StackOverflow and a friend with more experience in this aspect.
Another problem had to do with setting and changing state. I added a spinning loader to make the page a little "fancy" when waiting for a result. Then I noticed that the active loader component did not automatically remove the previous result. It simply pushed it to the bottom of the page. It was not part of my plan. So what I did was set isLoading
to false whenever a profile is successfully fetched or otherwise. Then I added a conditional statement that runs the component only when isLoading
is true.
// in App.js
...
const [isLoading, setIsLoading] = useState(false);
const [result, setResult] = useState('')
const [error, setError] = useState(false)
const getResult = async(name) => {
return fetch(input)
.then(async (res) => {
// check for and throw errors if necessary
return res.json()
})
.then((data) => {
setResult(data)
setIsLoading(false)
})
.catch((err) => {
setError(`${err.message}`)
setIsLoading(false)
});
}
// in Search.js
...
{isLoading ? <Loader /> : null}
I am assuming there is a better way to go about this, but this works for now. Brainstorming this problem gave me a clearer understanding of components and states.
That is all for this task. It's fascinating the things you can do with another application's API and the many ways you can manipulate/present the data if any.
Thanks for reading!
You can view the web page here. Feel free to test on both desktop and mobile screens. Feedback will be appreciated 🙏🏽