Projects

Joke Generator

2021·1 min read

JavaScript
HTML
CSS
Link (opens in a new tab)GitHub (opens in a new tab)

One button, one joke. Press it and it fetches a dad joke from icanhazdadjoke and swaps the text in place.

One button, one joke. Press it and it fetches a dad joke from icanhazdadjoke and swaps the text in place.

Live demo →

Stack#

Plain HTML, CSS and JavaScript. No framework, no build step, no dependencies — an index.html, a main.css and about thirty lines in main.js, deployed to GitHub Pages.

The point of it#

The interesting part is not the punchline, it is the request.

icanhazdadjoke returns HTML by default and only returns JSON if you ask for it:

async function generateJoke() {
  const configs = {
    headers: {
      Accept: 'application/json',
    },
  }
 
  const response = await fetch('https://icanhazdadjoke.com', configs)
  const data = await response.json()
 
  jokeElement.innerHTML = data.joke
}

Drop that Accept header and you get a page of markup where you expected an object — with a 200 OK status and nothing in the response to explain why response.json() just threw. It is a good early lesson that a URL is not an API: the headers are part of the contract.

Both versions are kept#

main.js still carries the original .then chain, commented out, directly above the async/await rewrite that replaced it. Reading them next to each other is the clearest illustration of what await actually removes, so it is left in rather than tidied away.

Known limitations#

  • No error handling. There is no try/catch and no response.ok check. If the request fails, the promise rejects into nothing and the button silently does nothing — from the user's side, indistinguishable from a broken page. Wrapping the call and writing the failure into the same element the joke would have filled is two lines and makes the interface honest about its state.
  • No loading state. A slow response leaves the previous joke on screen with no indication that a new one is coming.
  • innerHTML for a string that could contain markup. textContent is the correct choice here; the API is trusted, but the habit is not.

Running locally#

git clone https://github.com/Vette1123/Fetch-jokes-api.git
cd Fetch-jokes-api
# open index.html in a browser — no build, no server needed

The API needs no key and allows cross-origin requests.


Built by Mohamed Gado

More projects

  • Hadeed — Gym Workout Log2026 · Flutter
  • Water gallon calculator2021 · JavaScript
  • Khazna — Pocket Vault for Links, Notes & Lists2026 · React Native
All projects