Building a Quote Generator: Challenges and Lessons
Tags: showdev, react, learning, frontend
Published: 2023-09-27 09:50:08

I started learning how to code on [freeCodeCamp](https://www.freecodecamp.org/) in March 2021. From then until September 2021, I was pretty consistent with my learning. During that time, I completed the [Responsive Web Design Certification](https://www.freecodecamp.org/certification/nzubeifechukwu/responsive-web-design) and moved on to the next certification in the curriculum, JavaScript Algorithms and Data Structures.

I got stuck on the last project of this second certification, the Cash Register project. After battling with this project for a while, I decided to move on to the next certification, Front End Development Libraries.

I completed the interactive lessons without much hassle. It was time to build the projects, the first of which was the Random Quote Machine, but I didn’t know how to proceed. It seemed like I had learned nothing from the lessons. I decided to work on the other projects and come back later to the Quote Generator, but it was the same story.

Ultimately, I realised that I needed more resources to pull off these projects, so I began learning React on YouTube, depending mostly on [John Smilga’s courses](https://www.youtube.com/@CodingAddict) on the [freeCodeCamp channel](https://www.youtube.com/@freecodecamp). Due to some circumstances, I didn’t complete any of the videos. But I always had in mind to return to those freeCodeCamp projects and complete them.

Almost two years later, in August 2023, I was back again on YouTube viewing [John Smilga’s React 18 course](https://www.youtube.com/watch?v=2-crBg6wpp0). I completed this one, the over 14-hour-long video. Then I went back to the freeCodeCamp website to continue from where I stopped two years ago.

How I built the [Random Quote Machine](https://www.freecodecamp.org/learn/front-end-development-libraries/front-end-development-libraries-projects/build-a-random-quote-machine) is the subject of this article. I’ll describe my process, dwelling more on the challenges I encountered, lessons learned and possible next steps, without giving much away to anyone who intends to try out the project.

## CONTENTS

- Introduction
- Prerequisites
- Technologies and third-party services used
- Workflow
- Challenges
- Next steps
- Conclusion

## Introduction
The quote generator (I prefer this name to the verbose _random quote machine_) is a web app that displays a new quote on a button click. It also has a button to share the generated quote on Twitter.

This is not a how-to article, as I wouldn’t want to spoil the fun for anyone who may want to undertake building this app. My aim is just to share my process, not necessarily to teach how I built it.

## Prerequisites
To follow along with the article, especially the section on Workflow, you need a basic knowledge of:

- JavaScript (ES6)
- the ReactJS library

## Technologies and third-party services used
Besides React and CSS, I used the following technologies and/or third-party services for this project:

- **[API Ninjas's Quotes API](https://api-ninjas.com/api/quotes)** to get the quotes displayed by the app
- the **Axios** HTTP client to make API calls

## Workflow
I used the Vite local development server to install the starter files for the project. After launching the React app and making sure that changes in the `App.jsx` file reflected on the screen, my routine was to pick a particular feature and implement it.

I began by studying the Quotes API documentation. When I felt I’d understood how the API works, I proceeded to test it out in the `App.jsx` file. I logged the response of the API call to the console to have a full picture.

```
// some code
const displayQuote = async () => {
  const resp = await axios({
    url: "https://api.api-ninjas.com/v1/quotes",
    headers: { "X-Api-Key": "bdH0ad6RQC1YLqvfnOyogQ==SsiqwgM4LOP2vD9S" },
  });
  console.log(resp);
};
// more code
```

The response is an object, and the property of interest is the `data` property.

![Inspecting the response of the API call](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3hnhymoafdwxqecy0bei.png)

This `data` property is an array of 1 item. This item is an object with the following properties: `quote`, `author` and `category`.

Having understood the nature of the response, I imported React’s `useState` hook and set up the `quote` state and the `setQuote` function.

```
import { useState } from "react";

function App() {
  const [quote, setQuote] = useState({
    quote: "It does not matter how slowly you go as long as you do not stop.",
    author: "Confucius",
    category: "growth",
  });
  // more code
}
```

I relied on the format of `resp.data[0]` in the console to provide default values for the `quote`, `author` and `category` properties.

Next, I set up the JSX, populating the relevant HTML elements with the `quote` and `author`. I also set the `onClick` event on the `.new-quote` button equal to the `displayQuote` function.

```
return (
    <>
      <main style={{ color: color }} className="quote-box">
        <div className="quote">
          <p className="text">&quot;{quote.quote}&quot;</p>
          <p className="author">– {quote.author}</p>
        </div>
        <div className="btn-share">
          <button
            type="button"
            onClick={displayQuote}
            className="new-quote"
          >
            new quote
          </button>
        </div>
      </main>
    </>
  );
```

With the display new quote feature working properly, it was time to face the _tweet quote_ functionality. This was the first real challenge I encountered, as I wasn’t sure how to implement it. So, I googled _twitter share button react_. The search results included some articles on the `react-share` library, a library I didn’t know about. This library makes it possible to share your web app (or a part of it) on Social Media (Facebook, Twitter and/or Instagram). The results page also showed a resource on [Tweet Web Intent](https://developer.twitter.com/en/docs/twitter-for-websites/tweet-button/guides/web-intent), which was what I finally used.

```
<a
  className="tweet-quote"
  href={`https://twitter.com/intent/tweet?text="${quote.quote}"%0D%0D${quote.author}&hashtags=quote,${quote.category}`}
  target="_blank"
  rel="noreferrer"
  style={{ backgroundColor: color }}
 >
   <TweetIcon />
 </a>
```

At this point, the quote generator was practically complete. What was left was to add some CSS to improve the visual appeal, but I wouldn’t dwell on that.

## Challenges
In addition to implementing the _share quote on Twitter_ feature, I encountered the following challenges while building this quote generator:

- The background colour of the entire app changes with the quotes. Implementing this feature wasn’t straightforward, since I needed to set it up on the `<body>` element. React template files, as far as I know, are organised in such a way that the `<body>` element is part of the `index.html` file, and I had virtually no work to do in this file. My workaround was to use Vanilla JS to manipulate the `<body>` element in the `App.jsx` file.

```
const [color, setColor] = useState("#F39BA3");
document.body.style = `background: ${color};`;
```

- Changing the colour of the tweet icon was also challenging. I found out from my research that changing the `fill` attribute of the `<path>` child element of the `<svg>` element would give the desired result.

```
<svg
    xmlns="http://www.w3.org/2000/svg"
    height="1em"
    viewBox="0 0 512 512"
>
    <path
        d="M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z"
        fill="white"
    />
</svg>
```

## Next steps
Several alternatives were available to me while building this app.

For state management, I could have used either the `useRef` hook or the `Redux toolkit` instead of the `useState` hook. My choice of `useState` came down to the fact that there weren’t too many state values. Also, as this is my first React app, it made sense to go for the more common `useState`. There will definitely be opportunities in future to use `useRef` and `Redux`.

I’ve hinted in an earlier section that I could have used the `react-share` library instead of the Tweet Web Intent. To get some practice with this library, I may incorporate functionality to share the quotes on Facebook and Instagram.

## Conclusion
I enjoyed working on this Quote Generator app. It is my first React app. Building this app really improved my knowledge of React and CSS. It wasn’t without its challenges, but I’m happy I persevered until the end. While there is room for improvement, I’m proud of my achievement.

You can see the [app here](https://nzubeifechukwu-quote-generator.netlify.app/) and the [GitHub repo here](https://github.com/nzubeifechukwu/quote-generator).