From ce3d13d24b8090d4aac771be78a76de7973f5e74 Mon Sep 17 00:00:00 2001 From: Malusi Skunyana Date: Fri, 15 Aug 2025 19:33:22 +0200 Subject: [PATCH 1/5] Add HTML structure for XKCD comic viewer with random comic button --- fetch/programmer-humour/index.html | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 fetch/programmer-humour/index.html diff --git a/fetch/programmer-humour/index.html b/fetch/programmer-humour/index.html new file mode 100644 index 00000000..5102ad86 --- /dev/null +++ b/fetch/programmer-humour/index.html @@ -0,0 +1,20 @@ + + + + + + Programmer Humour - XKCD Comics + + + +

😂 Programmer Humour

+ +
+

Loading comic...

+
+ + + + + + \ No newline at end of file From 5a88cd1e8f1626b2a9d93413bb3ac695f6877842 Mon Sep 17 00:00:00 2001 From: Malusi Skunyana Date: Fri, 15 Aug 2025 19:34:47 +0200 Subject: [PATCH 2/5] Implement random XKCD comic fetching with button for new comic --- fetch/programmer-humour/script.js | 55 +++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 fetch/programmer-humour/script.js diff --git a/fetch/programmer-humour/script.js b/fetch/programmer-humour/script.js new file mode 100644 index 00000000..eeae6a76 --- /dev/null +++ b/fetch/programmer-humour/script.js @@ -0,0 +1,55 @@ +let latestNum = null; // Store latest comic number + +async function fetchRandomComic() { + const container = document.getElementById('comic-container'); + + try { + // Get latest comic number if not already fetched + if (!latestNum) { + const latestResponse = await fetch('https://xkcd.now.sh/?comic=latest'); + if (!latestResponse.ok) { + throw new Error(`HTTP error getting latest: ${latestResponse.status}`); + } + const latestData = await latestResponse.json(); + latestNum = latestData.num; + } + + // Pick a random comic number between 1 and latestNum + const randomNum = Math.floor(Math.random() * latestNum) + 1; + + // Fetch the random comic + const response = await fetch(`https://xkcd.now.sh/?comic=${randomNum}`); + if (!response.ok) { + throw new Error(`HTTP error getting comic: ${response.status}`); + } + + const data = await response.json(); + console.log('Fetched comic data:', data); + + // Clear container + container.innerHTML = ''; + + // Add title + const title = document.createElement('div'); + title.className = 'comic-title'; + title.textContent = `#${data.num} – ${data.title}`; + container.appendChild(title); + + // Add comic image + const img = document.createElement('img'); + img.src = data.img; + img.alt = data.alt; + img.title = data.alt; + container.appendChild(img); + + } catch (error) { + console.error('Error fetching the comic:', error); + container.innerHTML = `

Failed to load comic. Try again later.

`; + } +} + +// Load first comic when page starts +fetchRandomComic(); + +// Add button click handler +document.getElementById('new-comic-btn').addEventListener('click', fetchRandomComic); \ No newline at end of file From 2a4170ba031213de9b04fd0ec18985b96e593621 Mon Sep 17 00:00:00 2001 From: Malusi Skunyana Date: Fri, 15 Aug 2025 19:35:50 +0200 Subject: [PATCH 3/5] Add styling for comic viewer and button --- fetch/programmer-humour/style.css | 43 +++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 fetch/programmer-humour/style.css diff --git a/fetch/programmer-humour/style.css b/fetch/programmer-humour/style.css new file mode 100644 index 00000000..3736e082 --- /dev/null +++ b/fetch/programmer-humour/style.css @@ -0,0 +1,43 @@ +body { + font-family: Arial, sans-serif; + text-align: center; + background-color: #f4f4f4; + margin: 0; + padding: 20px; +} + +h1 { + color: #333; +} + +#comic-container { + margin-top: 20px; +} + +.comic-title { + font-weight: bold; + font-size: 1.2rem; + margin-bottom: 10px; +} + +#comic-container img { + max-width: 100%; + height: auto; + border: 2px solid #ccc; + border-radius: 8px; +} + +button { + margin-top: 20px; + padding: 10px 15px; + font-size: 1rem; + background-color: #0078d4; + color: white; + border: none; + border-radius: 6px; + cursor: pointer; +} + +button:hover { + background-color: #005a9e; +} \ No newline at end of file From 8170907846f0ce5a34bd708e0a7609e203958f5f Mon Sep 17 00:00:00 2001 From: Malusi Skunyana Date: Sat, 16 Aug 2025 20:06:09 +0200 Subject: [PATCH 4/5] Refactor: extract repeated fetch logic into reusable fetchJson() helper --- fetch/programmer-humour/script.js | 39 +++++++++++++++---------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/fetch/programmer-humour/script.js b/fetch/programmer-humour/script.js index eeae6a76..56b5a924 100644 --- a/fetch/programmer-humour/script.js +++ b/fetch/programmer-humour/script.js @@ -1,41 +1,39 @@ -let latestNum = null; // Store latest comic number +// Reusable function for fetching JSON with error handling +async function fetchJson(url) { + const response = await fetch(url); + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + return await response.json(); +} + +let latestNum = null; // cache latest comic number async function fetchRandomComic() { const container = document.getElementById('comic-container'); try { - // Get latest comic number if not already fetched + // Get latest comic number if not cached if (!latestNum) { - const latestResponse = await fetch('https://xkcd.now.sh/?comic=latest'); - if (!latestResponse.ok) { - throw new Error(`HTTP error getting latest: ${latestResponse.status}`); - } - const latestData = await latestResponse.json(); + const latestData = await fetchJson('https://xkcd.now.sh/?comic=latest'); latestNum = latestData.num; } - // Pick a random comic number between 1 and latestNum + // Pick a random comic number const randomNum = Math.floor(Math.random() * latestNum) + 1; // Fetch the random comic - const response = await fetch(`https://xkcd.now.sh/?comic=${randomNum}`); - if (!response.ok) { - throw new Error(`HTTP error getting comic: ${response.status}`); - } - - const data = await response.json(); + const data = await fetchJson(`https://xkcd.now.sh/?comic=${randomNum}`); console.log('Fetched comic data:', data); - // Clear container + // Render comic container.innerHTML = ''; - // Add title const title = document.createElement('div'); title.className = 'comic-title'; title.textContent = `#${data.num} – ${data.title}`; container.appendChild(title); - // Add comic image const img = document.createElement('img'); img.src = data.img; img.alt = data.alt; @@ -43,13 +41,14 @@ async function fetchRandomComic() { container.appendChild(img); } catch (error) { - console.error('Error fetching the comic:', error); + console.error('Error fetching comic:', error); container.innerHTML = `

Failed to load comic. Try again later.

`; } } -// Load first comic when page starts +// Load first comic on page load fetchRandomComic(); // Add button click handler -document.getElementById('new-comic-btn').addEventListener('click', fetchRandomComic); \ No newline at end of file +document.getElementById('new-comic-btn') + .addEventListener('click', fetchRandomComic); \ No newline at end of file From 90f754c8dc86846ec8c9f8d2998ab87f01de21d1 Mon Sep 17 00:00:00 2001 From: Malusi Skunyana Date: Sat, 16 Aug 2025 20:29:55 +0200 Subject: [PATCH 5/5] Chore: remove console.log debugging statement from comic fetch --- fetch/programmer-humour/script.js | 1 - 1 file changed, 1 deletion(-) diff --git a/fetch/programmer-humour/script.js b/fetch/programmer-humour/script.js index 56b5a924..ef7b8f80 100644 --- a/fetch/programmer-humour/script.js +++ b/fetch/programmer-humour/script.js @@ -24,7 +24,6 @@ async function fetchRandomComic() { // Fetch the random comic const data = await fetchJson(`https://xkcd.now.sh/?comic=${randomNum}`); - console.log('Fetched comic data:', data); // Render comic container.innerHTML = '';