Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
39 changes: 26 additions & 13 deletions 3-UsingAPIs/Week2/assignment/ex1-programmerFun/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,29 +16,42 @@ Full description at: https://github.com/HackYourFuture/Assignments/blob/main/3-U
url with `.shx`. There is no server at the modified url, therefore this
should result in a network (DNS) error.
------------------------------------------------------------------------------*/
function requestData(url) {
// TODO return a promise using `fetch()`
async function requestData(url) {
try {
const response = await fetch(url);

if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}

const data = await response.json();
return data;
} catch (error) {
throw error;
}
}

function renderImage(data) {
// TODO render the image to the DOM
const img = document.createElement('img');
img.src = data.img;
document.body.appendChild(img);
console.log(data);
}

function renderError(error) {
// TODO render the error to the DOM
const h1 = document.createElement('h1');
h1.textContent = error.message || error;
document.body.appendChild(h1);
console.log(error);
}

// TODO refactor with async/await and try/catch
function main() {
requestData('https://xkcd.now.sh/?comic=latest')
.then((data) => {
renderImage(data);
})
.catch((error) => {
renderError(error);
});
async function main() {
try{
const data = await requestData('https://xkcd.now.sh/?comic=latest');
renderImage(data);
} catch (error) {
renderError(error);
}
}

window.addEventListener('load', main);
72 changes: 65 additions & 7 deletions 3-UsingAPIs/Week2/assignment/ex2-pokemonApp/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,76 @@ Use async/await and try/catch to handle promises.
Try and avoid using global variables. As much as possible, try and use function
parameters and return values to pass data back and forth.
------------------------------------------------------------------------------*/
function fetchData(/* TODO parameter(s) go here */) {
// TODO complete this function
async function fetchData(url) {
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
const data = await response.json();
return data;
} catch (error) {
console.error('Fetch error:', error);
throw error;
}
}

function fetchAndPopulatePokemons(/* TODO parameter(s) go here */) {
// TODO complete this function
async function fetchAndPopulatePokemons() {
const url = 'https://pokeapi.co/api/v2/pokemon?limit=150';
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

love it!
It's really good practice to keep such things in separate variables and not define them right in the functions like this: fetchData('https://pokeapi.co/api/v2/pokemon?limit=151');

Great that you did it!

try {
const data = await fetchData(url);
const select = document.querySelector('select');
select.innerHTML = '';

data.results.forEach((pokemon) => {
const option = document.createElement('option');
option.value = pokemon.url;
option.textContent = pokemon.name;
select.appendChild(option);
});
} catch (error) {
console.error('Error fetch pokemon list:', error);
}
}

function fetchImage(/* TODO parameter(s) go here */) {
// TODO complete this function
async function fetchImage(pokemonUrl) {
try {
const data = await fetchData(pokemonUrl);
const img = document.querySelector('img');
img.src = data.sprites.front_default;
img.alt = `${data.name} Pokemon sprite`;
} catch (error) {
console.error('Error fetch image:', error);
}
}

function main() {
// TODO complete this function
const button = document.createElement('button');
button.id = 'get-button';
button.textContent = 'get pokemon';
document.body.appendChild(button);

const select = document.createElement('select');
select.id = 'pokemon-select';
document.body.appendChild(select);

const option = document.createElement('option');
option.value = '';
option.textContent = 'Select a Pokemon';
select.appendChild(option);

const img = document.createElement('img');
img.id = 'pokemon-img';
img.alt = `select a pokemon to see it image `;
document.body.appendChild(img);

button.addEventListener('click', fetchAndPopulatePokemons);

select.addEventListener('change', (event) => {
if (event.target.value) {
fetchImage(event.target.value);
}
});
}

window.addEventListener('load', main);
97 changes: 96 additions & 1 deletion 3-UsingAPIs/Week2/assignment/ex2-pokemonApp/style.css
Original file line number Diff line number Diff line change
@@ -1 +1,96 @@
/* add your styling here */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}

body {
font-family: 'Poppins', sans-serif;
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-start;
min-height: 100vh;
background-color: #f5f5f5;
color: #222;
text-align: center;
padding: 40px 20px;
}

h1 {
font-size: 2rem;
color: #333;
margin-bottom: 25px;
}

#get-button {
padding: 10px 20px;
font-size: 16px;
color: #fff;
background-color: #4caf50;
border: none;
border-radius: 6px;
cursor: pointer;
transition: background 0.2s ease, transform 0.2s ease;
margin-bottom: 20px;
}

#get-button:hover {
background-color: #45a049;
transform: scale(1.05);
}

select {
padding: 10px 15px;
font-size: 16px;
border: 1px solid #ccc;
border-radius: 6px;
background-color: #fff;
cursor: pointer;
width: 200px;
margin-bottom: 20px;
transition: border-color 0.2s ease;
}

select:focus {
border-color: #4caf50;
outline: none;
}

img {
max-width: 250px;
max-height: 250px;
border-radius: 8px;
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
transition: transform 0.2s ease;
margin-top: 20px;
}

img:hover {
transform: scale(1.05);
}

h1.error {
color: #e53935;
font-size: 1.5rem;
margin-top: 20px;
}

@media (max-width: 480px) {
body {
padding: 20px 10px;
}

h1 {
font-size: 1.8rem;
}

img {
max-width: 180px;
max-height: 180px;
}

select, #get-button {
width: 160px;
}
}
26 changes: 13 additions & 13 deletions 3-UsingAPIs/Week2/assignment/ex3-rollAnAce.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,21 @@ import { rollDie } from '../../helpers/pokerDiceRoller.js';
* @param {DieFace} desiredValue
* @returns {Promise<DieFace>}
*/
export function rollDieUntil(desiredValue) {
// TODO rewrite this function using async/await
return rollDie().then((value) => {
if (value !== desiredValue) {
return rollDieUntil(desiredValue);
}
return value;
});
export async function rollDieUntil(desiredValue) {
let value;
while (value !== desiredValue) {
value = await rollDie();
}
return value;
}

// TODO refactor this function to use try/catch
function main() {
rollDieUntil('ACE')
.then((results) => console.log('Resolved!', results))
.catch((error) => console.log('Rejected!', error.message));
async function main() {
try {
const result = await rollDieUntil('ACE');
console.log('Resolved!', result);
} catch (error) {
console.log('Rejected!', error.message);
}
}

// ! Do not change or remove the code below
Expand Down
20 changes: 12 additions & 8 deletions 3-UsingAPIs/Week2/assignment/ex4-diceRace.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,24 @@ import { rollDie } from '../../helpers/pokerDiceRoller.js';

export function rollDice() {
const dice = [1, 2, 3, 4, 5];
// TODO complete this function; use Promise.race() and rollDie()
rollDie(1); // TODO placeholder: modify as appropriate
const diceRolls = dice.map(rollDie);
return Promise.race(diceRolls);
}

// Refactor this function to use async/await and try/catch
function main() {
rollDice()
.then((results) => console.log('Resolved!', results))
.catch((error) => console.log('Rejected!', error.message));
async function main() {
try {
const result = await rollDice();
console.log('resolved:', result);
} catch (error) {
console.error('rejected :', error.message);
}
}

// ! Do not change or remove the code below
if (process.env.NODE_ENV !== 'test') {
main();
}

// TODO Replace this comment by your explanation that was asked for in the assignment description.
// Even after Promise.race() returns the first result, the other dice keep rolling
// because their promises are already running. Promise.race() only waits for the
// first one to finish; it does not stop the rest.
25 changes: 20 additions & 5 deletions 3-UsingAPIs/Week2/assignment/ex5-vscDebug.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,18 @@ async function getData(url) {

function renderLaureate({ knownName, birth, death }) {
console.log(`\nName: ${knownName.en}`);
console.log(`Birth: ${birth.date}, ${birth.place.locationString}`);
console.log(`Death: ${death.date}, ${death.place.locationString}`);

if (birth) {
console.log(`Birth: ${birth?.date || 'Unknown'}, ${birth?.place?.locationString || 'Unknown'}`);
} else {
console.log(`Birth: Unknown`);
}

if (death) {
console.log(`Death: ${death?.date || 'Unknown'}, ${death?.place?.locationString || 'Unknown'}`);
} else {
console.log(`Death: still alive`);
}
}

function renderLaureates(laureates) {
Expand All @@ -20,13 +30,18 @@ function renderLaureates(laureates) {

async function fetchAndRender() {
try {
const laureates = getData(
const data = await getData(
'http://api.nobelprize.org/2.0/laureates?birthCountry=Netherlands&format=json&csvLang=en'
);
renderLaureates(laureates);

if (Array.isArray(data.laureates)) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

It's good to make sure it's safe, but in this case, it might be redundant as it seems like the API always returns an array, even when the params are wrong, like unknown country

Screenshot 2025-10-13 at 16 38 28

You don't need to make any changes, just wanted to highlight it

renderLaureates(data.laureates);
} else {
console.error('No laureates found.');
}
} catch (err) {
console.error(`Something went wrong: ${err.message}`);
}
}

fetchAndRender();
fetchAndRender();
Loading