Random Quote – Vanilla JavaScript: Using various front end stacks

9 min read

Building a random quote machine with Vanilla JavaScript

This is Part 1 of an 11-part series. Each part using a different front end stack (different flavor). Starring in this flavor: Vanilla JavaScript.

Goal with this series of writings: Build a random quote machine with 19 11 different front end stacks and ship quickly.

True that…

There are always (at least) two ways to solve a problem. One is faster, the other you just don’t know yet.

You can read more about this project’s background on the project’s page.

So, what should the random quote machine do? It should spit out quotes.

These are the user stories:

  1. As a random person on the web inspired by Greta Thunberg (or not - see note below), I want to be welcomed by a nice inspirational quote from Greta Thunberg so that I become (even more) inspired.

  2. As a random person on the web, I want to be able to click a button to get a new inspirational quote from Greta Thunberg so that I can pimp my inspiration levels.

  3. As a random person on the web, I want to be able to share on Twitter the quote the random quote machine gives me so that I can share my source of inspiration with the world.

Random Greta Gif

Here are the different flavors available:

  1. HTML + CSS + Vanilla JS + quotes array
  2. HTML + CSS + Vanilla JS + JSON with quotes
  3. HTML + CSS + Vanilla JS + quotes REST API
  4. HTML + Vanilla JS + SAAS + quotes array (nah, because let’s be opinionated about SASS)
  5. HTML + Vanilla JS + Bootstrap + quotes array (nah, because let’s be opinionated about Bootstrap)
  6. HTML + CSS + JQuery + JSON with quotes (nah, because let’s be opinionated about JQuery)
  7. HTML + CSS + Redux + quotes array
  8. HTML + CSS + Redux + JQuery + JSON with quotes (nah, because let’s be opinionated about JQuery)
  9. HTML + CSS + Redux + Redux Thunk + JSON with quotes
  10. HTML + CSS + React + quotes array
  11. HTML + CSS + React + JSON with quotes
  12. HTML + CSS + React Hooks + quotes array
  13. HTML + CSS + React Hooks + JSON with quotes
  14. HTML + CSS + React + Redux + quotes array (nah, because let’s be bullish about writing any new components with React Hooks)
  15. HTML + CSS + React + Redux + Redux Thunk + JSON with quotes (nah, because let’s be bullish about writing any new components with React Hooks)
  16. HTML + CSS + React Hooks + Redux + quotes array
  17. HTML + CSS + React Hooks + Redux + Redux Thunk + JSON with quotes
  18. HTML + CSS + React Hooks + Redux Hooks + quotes array (nah, because let’s be opinionated about Redux Hooks)
  19. HTML + CSS + React Hooks + Redux Hooks + Redux Thunk + JSON with quotes (nah, because let’s be opinionated about Redux Hooks)

In Part 2 (to be posted next week), I will cover a second flavor and will be storing the quotes in a separate JSON file.

If you’re curious about the next flavors and would like to make a writer very happy today, you should join Morse Wall’s newsletter.


This is a simple project. Flavor #1 has essentially 3 lines of functional JavaScript code.

The URL to the source code for each flavor is linked at the bottom of each section in this series.

Flavor #1: HTML + CSS + Vanilla JS + quotes array

HTML and CSS aside (they can be found in the Github repo for flavor #1). I’m into Vanilla JavaScript universe in flavor #1. The data (quotes) are inside an array.

I’ve scraped the quotes with the help of Spider, a point&click scraping tool built by Amie-Chen. So, with the help of Spider, you can also go ahead and easily collect quotes from any prolific public figure you choose.

When I was done scraping, I’ve then downloaded a JSON from Spider and copy-pasted the quotes into an array inside my script.js. There are only 3 quotes in the code snippet below (so I can illustrate the point), but many more quotes in the array in production.

// script.js
//defining an array for the quotes
const quotes = [
  {
    quoteText:
      '"Many of you appear concerned that we are wasting valuable lesson time, but I assure you we will go back to school the moment you start listening to science and give us a future."',
    quoteAuthor: "Greta Thunberg"
  },
  {
    quoteText:
      '"I was fortunate to be born in a time and place where everyone told us to dream big. I could become whatever I wanted to. I could live wherever I wanted to. People like me had everything we needed and more. Things our grandparents could not even dream of. We had everything we could ever wish for and yet now we may have nothing. Now we probably don’t even have a future any more."',
    quoteAuthor: "Greta Thunberg"
  },
  {
    quoteText:
      '"That future was sold so that a small number of people could make unimaginable amounts of money. It was stolen from us every time you said that the sky was the limit, and that you only live once. You lied to us. You gave us false hope. You told us that the future was something to look forward to."',
    quoteAuthor: "Greta Thunberg"
  }
];

Given I want a random quote to be ready for me when the quote machine loads, I need to call a function (that I still need to define) that fetches a random quote and renders it my HTML.

// script.js
// inject a quote on screen when app loads
injectQuote();

And given I also want a new random quote when the user clicks a button, I’ve added a click event listener to the HTML element with new-quote id.

In the HTML, setting up new-quote id (as always, you can check the full source code in the repo. Also linked at the bottom of this write-up):

<!-- index.html -->
<button id="new-quote" class="new-quote">Get New Quote</button>

Back to JavaScript, adding the click event listener:

// script.js
//inject a quote on screen when "Get New Quote" button is clicked
document.getElementById("new-quote").addEventListener("click", function() {
  injectQuote();
});

injectQuote function

The bit missing is to define the function I’ve mentioned above that will fetch a random quote from my quotes array and render it in my HTML. I’m calling that function injectQuote.

// script.js
//function to access random quote from array and inject it together with author on HTML
function injectQuote() {}

injectQuote needs to pick a random quote from quotes, so let’s do that first thing. I’ll be incrementally expanding injectQuote in each of the following code snippets, to the point it will be clear it would have been better to break injectQuote down into smaller functions (huh…)

// script.js
//function to access random quote from array and inject it together with author on HTML
function injectQuote() {
  //access random quote from quote array
  let randomQuote = quotes[Math.floor(Math.random() * quotes.length)];
}

After fetching a random quote, injectQuote should render the quote text and and quote author in my HTML.

// script.js
//function to access random quote from array and inject it together with author on HTML
function injectQuote() {
  //access random quote from quote array
  let randomQuote = quotes[Math.floor(Math.random() * quotes.length)];
  //inject random quote on HTML
  document.getElementById("text").innerHTML = randomQuote.quoteText;
  let quoteTextElem = randomQuote.quoteText;
  //inject author on HTML
  document.getElementById("author").innerHTML = "- " + randomQuote.quoteAuthor;
  let quoteAuthorElem = " - " + randomQuote.quoteAuthor;
}

With the above in production, the random quote machine beautifully renders a new quote upon page load and when a user clicks a button requesting a new quote.

Making the machine tweet

However, I haven’t made the Tweet Quote button work yet. So, to invoke Twitter Web Intents, injectQuote should URL-encode the tweet text, concatenate it with https://twitter.com/intent/tweet?text= and pass it to the HTML element’s href.

In the HTML, setting up tweet-quote id:

<!-- index.html -->
<button class="tweet-quote">
<a id="tweet-quote" href="twitter.com/intent/tweet" target="_blank"><i class="fab fa-twitter"></i>Tweet Quote</a>
</button>

And back to JavaScript:

//script.js
//function to access random quote from array and inject it together with author on HTML
function injectQuote() {
  //access random quote from quote array
  let randomQuote = quotes[Math.floor(Math.random() * quotes.length)];
  //inject random quote on HTML
  document.getElementById("text").innerHTML = randomQuote.quoteText;
  let quoteTextElem = randomQuote.quoteText;
  //inject author on HTML
  document.getElementById("author").innerHTML = "- " + randomQuote.quoteAuthor;
  let quoteAuthorElem = " - " + randomQuote.quoteAuthor;
  //defining tweet text
  let contentQuote = quoteTextElem + quoteAuthorElem;
  //generate url available for Twitter intent and inject url on HTML
  document.getElementById("tweet-quote").href =
    "https://twitter.com/intent/tweet?text=" + contentQuote;
}

Ok, now the random quote machine ships all the required user stories.

The issue here though is that some of Greta’s quotes are longer than 280 characters (better than 140 char, I know. Thanks @jack). I have to truncate the quote text to allow the user to tweet the quote without having to delete characters. injectQuote (now already doing far too much for a single function) needs some adjustments.

// script.js
//function to access random quote from array and inject it together with author on HTML
function injectQuote() {
  //access random quote from quote array
  let randomQuote = quotes[Math.floor(Math.random() * quotes.length)];
  //inject random quote on HTML
  document.getElementById("text").innerHTML = randomQuote.quoteText;
  let quoteTextElem = randomQuote.quoteText;
  //inject author on HTML
  document.getElementById("author").innerHTML = "- " + randomQuote.quoteAuthor;
  let quoteAuthorElem = " - " + randomQuote.quoteAuthor;
  //truncating quote text in case full tweet gets to be over 280 characters
  let contentQuote = quoteTextElem + quoteAuthorElem;
  if (contentQuote.length > 280) {
    let charCountAuthor = quoteAuthorElem.length;
    const extraStylingChar = "..." + '"';
    let extraCharCount = extraStylingChar.length;
    let subString =
      quoteTextElem.substring(0, 280 - extraCharCount - charCountAuthor) +
      extraStylingChar +
      quoteAuthorElem;
    //generate url available for Twitter intent and inject url on HTML
    document.getElementById("tweet-quote").href =
      "https://twitter.com/intent/tweet?text=" + subString;
  } else {
    //generate url available for Twitter intent and inject url on HTML
    document.getElementById("tweet-quote").href =
      "https://twitter.com/intent/tweet?text=" + contentQuote;
  }
}

Done. The random quote machine is ready to receive any random person on the web.

If you think a great Greta Thunberg quote is missing, I’ll be happy to include it. Pull requests are more than welcome in the Github repo for flavor #1.

Live project Source code


In Part 2 (to be posted next week), I will cover a second flavor and will be storing the quotes in a separate JSON file.

If you’re curious about the next flavors, you should join Morse Wall’s newsletter. I think you’ll like it a lot!


So, what did you like about this post? Leave a comment or come say hello on Twitter!

Also, if you have built a random quote machine after reading this post, share it below as a comment. Really excited to see what you create!

Happy coding!

Enjoyed this content?

Help keep it coming by sending a donation or buying me coffees.
You can also join Morse Wall's newsletter, or subscribe to various site feeds to get notified of new posts or follow Morse Wall on social media.

Leave a comment

by Pat
by Pat