HomeTutorialsArticlesAbout MeContact

Create a Random Quote Machine in JavaScript | freeCodeCamp

Published in Tutorial
August 05, 2019
3 min read
Check out my Github for my free-to-read JavaScript Ebook that covers all the new features from ES6 to 2021. If you want find a great place for interactive tutorials, i recommend Educative where you can find my JavaScript course
This website contains affiliate links.

This project is based on a project from the freeCodeCamp Curriculum that you can find here.

The goals of this project is to be able to fetch random quote from a public api and display them on our page.

It’s a simple task suitable for beginners that will help you learn how to interact with public API to fetch and display data.

Demo of the Random Quote Machine

Once complete, our random quote machine will look like this:


 

The Task

  • Difficulty: Beginner
  • Tools: Text Editor of your choice
  • Duration: < 1 hour

Creating the HTML for the Random Quote Machine

Let’s first start by creating the structure of our project. Open your text editor and create an index.html file.

The project is very simple, we only need a container where to display quotes, a button to fetch them and a twitter button to share them.

First add this to the head of your html file:

<link
  rel="stylesheet"
  href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"
/>

We are importing font awesome as we are going to use one of their icon for our twitter button.

Next, let’s create the structure of our project which will be like this:

  • container div that will change color every time we get a new quote
    • an inner div
      • a div for the quote
      • a div for the two buttons
<div class="page-content randomBgColor">
  <div id="quote-box">
    <div id="text">
      <i class="fa fa-quote-left randomTxtColor" aria-hidden="true" />
      <span id="quoteText" class="randomTxtColor" />
      <br />
      <span id="quoteAuthor" class="randomTxtColor" />
    </div>

    <div id="buttonBox">
      <a
        id="twitter-share-button"
        target="blank"
        href="twitter.com/intent/tweet"
        data-text="custom share text"
      >
        <i class="fa fa-twitter randomBgColor" aria-hidden="true"></i>
      </a>
      <button id="new-quote" class="cta randomBgColor">New Quote</button>
    </div>
  </div>
</div>

As you can see the structure is quite simple, the classes i have added are mostly for styling and for our JavaScript to target the correct elements in the DOM.

Styling the Random Quote Machine with CSS

You can skip this part if you want the Random Quote Machine to look differently but if you are interested in achieving the same result as mine, here is the style that I have used.

.randomBgColor {
  transition: background-color 1s ease;
}
.randomTxtColor {
  transition: color 1s ease;
}
#quote-box {
  max-width: 400px;
  width: 100%;
  min-height: 200px;
  height: auto;
  margin: 10% auto 10% auto;
  background-color: white;
  padding: 10px;
  padding-bottom: 20px;
  border-radius: 5%;
}
#text {
  padding: 25px;
}
.fa-quote-left {
  font-size: 55px;
  padding-right: 15px;
  display: inline-block;
  width: auto;
}
#quoteText {
  font-size: 25px;
  text-align: center;
  width: 70%;
}
#author {
  font-size: 16px;
  text-align: right;
  display: block;
  width: 100%;
}
#buttonBox {
  height: 50px;
  padding: 15px;
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-content: center;
}
.fa-twitter {
  font-size: 40px;
  padding: 5px 5px 0 5px;
  color: white;
}
#new-quote {
  padding: 0 10px;
  cursor: pointer;
  color: white;
  font-weight: bold;
  border-radius: 5px;
  border: none;
}
#new-quote:hover {
  opacity: 0.5;
}
.fa-twitter {
  border-radius: 20%;
  border: none;
}

#credit {
  display: block;
  margin: 0 auto;
  width: 150px;
  height: 15px;
  color: white;
}
#credit a,
#credit a:hover {
  color: inherit;
  text-decoration: none;
}

Adding JavaScript to the Random Quote Machine

This is the most important part of the tutorial, we will learn how to fetch data from the Forismatic API and display it in our page.

To start, let’s define the base URL where to make our API calls at the top of our JavaScript file:

const url =
  'https://api.forismatic.com/api/1.0/?method=getQuote&format=jsonp&lang=en&jsonp=displayQuote'

For simplicity we will create two function, one to get the quote from the API and one to change the color of our container div.

Let’s first start with the easiest one, changing color:

const colorRandomizer = () => {
  const myColors = ['#3498db', '#2ecc71', '#9b59b6', '#e74c3c', '#f1c40f'] //array of colors
  const randomNum = Math.floor(Math.random() * myColors.length) //generate random number

  const randomColor = myColors[randomNum]
  // modify bg and txt color with my random color
  // get the DOM element
  const bg = document.querySelector('.randomBgColor')
  // set the css attribute on it
  bg.setAttribute('style', `background-color: ${randomColor}`)

  const textElements = document.querySelectorAll('.randomTxtColor')
  for (const text of textElements) {
    // we have multiple elements where we want to change the text colors
    text.setAttribute('style', `color: ${randomColor}`)
  }
}

myColors is an array of colors and randomNum will be used to generate and store a random index of the myColors array. randomColor is then applied to both our container div and our quote text with .setAttribute.

Now let’s move on to fetching data from the API. There are multiple ways we can achieve that, here we are going to look at fetching data via JSONP which will allow us to quickly overcome the problem of getting content from two different origins (in this case our web page and the Forsimatic API). You can read more about the same-origin policy here.

The same-origin policy is a security mechanism that will restrict usage of resources coming from a different origin. To overcome this, we will inject a script tag in our html document and call that function when making a JSONP (‘JSON with padding’) request.

The response from our JSONP request will contain the JSON response from the API and a callback function to which we can pass any argument we want.

This type of request can be convenient but it also poses issues when the API server get’s compromised as it may lead to malicious code being injected in your page so be careful and use it only for trivial projects such as this one.

const getQuote = (data) => {
  // 1) here we are creating the callback function that we will pass to the JSONP request
  const callbackName = 'displayQuote'
  window[callbackName] = function (data) {
    delete window[callbackName]
    document.body.removeChild(script)
    callback(data)
  }

  // 2) we are injecting the script tag into our HTML
  const script = document.createElement('script')
  script.src =
    url + (url.indexOf('?') >= 0 ? '&' : '?') + 'callback=' + callbackName
  document.body.appendChild(script)
}

As you saw, we called our callback function displayQuote (const callbackName = 'displayQuote') so let’s define it. This will be the function called by our JSONP request and it will take care of passing the text and author of the quote to our HTML elements.

const displayQuote = (data) => {
  const currentQuote = data.quoteText
  const currentAuthor = data.quoteAuthor
  //add them to my html
  const text = document.querySelector('#quoteText')
  text.innerHTML = currentQuote
  const author = document.querySelector('#quoteAuthor')
  author.innerHTML = `- ${currentAuthor}`
  const twitter = document.querySelector('#twitter-share-button')
  twitter.setAttribute(
    'href',
    'https://twitter.com/intent/tweet?hashtags=quotes,Fcc&related=freecodecamp&text=' +
      encodeURIComponent('"' + currentQuote + '" ' + currentAuthor)
  )
}

We are saving the author and text of the quote in two variables and adding it to our HTML element by using .innerHTML. We are also passing those two values to the Twitter url so that when users press the button, the tweet will be pre-filled with our quote.

Awesome, we are just a few steps away from finishing this project.

Currently, if we try to click our button, nothing happens so let’s fix this.

document.querySelector('#new-quote').addEventListener('click', () => {
  getQuote(displayQuote)
})

What we did here was to add an event listener to our button which will fire the getQuote function with the displayQuote as a callback.

The last step to do now is to make it so that when the user visits the page for the first time, a quote will be fetched.

document.addEventListener('DOMContentLoaded', () => {
  getQuote(displayQuote);
}

Great, we are waiting for the page to load and then fire our getQuote function. This way, when you land on the page, a quote will already be there without having to press the button.

If you followed the instructions you should now have something that looks like the following:

javascript random quote machine



Tags

jstutorialsfreecodecamp
Previous Article
Tutorial - Create a Smooth Scrolling Navigation with JavaScript
complete guide to modern javascript book cover

Complete Guide to Modern JavaScript

Get the Course

Category

Article
Challenge
Tutorial

Related Posts

Create Pomodoro Clock in JavaScript Tutorial | freeCodeCamp
September 09, 2019
12 min
© 2022, All Rights Reserved.

Quick Links

TutorialsArticlesChallenges

Social Media