Skip to content
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions fetch/programmer-humour/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Programmer Humour - XKCD Comics</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>😂 Programmer Humour</h1>

<div id="comic-container">
<p>Loading comic...</p>
</div>

<button id="new-comic-btn">Show me another comic</button>

<script src="script.js"></script>
</body>
</html>
55 changes: 55 additions & 0 deletions fetch/programmer-humour/script.js
Original file line number Diff line number Diff line change
@@ -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();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You have two similar sets of code for fetching data. It might be a good idea to refactor the code into a function.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for great feedback! Indeed, the fetch logic was duplicated in two places. I have now refactored it into a reusable fetchJson() helper function. This keeps the code DRY, improves readability, and ensures that any future changes to error handling or response parsing only need to be made in one place. It should also make the code easier to extend if we add more API calls later.

console.log('Fetched comic data:', data);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When submitting a PR, it's best practices to remove debugging code to keep the code clean.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have removed the console.log statement so the code is cleaner. I will make sure to keep debugging output out of future PRs. Thank you for great feedback.


// 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 = `<p style="color:red;">Failed to load comic. Try again later.</p>`;
}
}

// Load first comic when page starts
fetchRandomComic();

// Add button click handler
document.getElementById('new-comic-btn').addEventListener('click', fetchRandomComic);
43 changes: 43 additions & 0 deletions fetch/programmer-humour/style.css
Original file line number Diff line number Diff line change
@@ -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;
}
Loading