Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
14 changes: 14 additions & 0 deletions .test-summary/TEST_SUMMARY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
## Test Summary

**Mentors**: For more information on how to review homework assignments, please refer to the [Review Guide](https://github.com/HackYourFuture/mentors/blob/main/assignment-support/review-guide.md).

### 3-UsingAPIs - Week2

| Exercise | Passed | Failed | ESLint |
|-------------------|--------|--------|--------|
| ex1-programmerFun | 5 | - | ✓ |
| ex2-pokemonApp | 5 | - | ✓ |
| ex3-rollAnAce | 7 | - | ✓ |
| ex4-diceRace | 7 | - | ✓ |
| ex5-vscDebug | - | - | ✓ |
| ex6-browserDebug | - | - | ✓ |
29 changes: 17 additions & 12 deletions 3-UsingAPIs/Week2/assignment/ex1-programmerFun/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,29 +16,34 @@ 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) {
const res = await fetch(url);
if (!res.ok) throw new Error(`HTTP error! Status: ${res.status}`);
return res.json();
Comment on lines +19 to +22

Choose a reason for hiding this comment

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

Good 👍

}

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);
Comment on lines +26 to 29

Choose a reason for hiding this comment

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

Don't forget to add an alt tag for web accessibility, and please remove debugging console.logs.

}

function renderError(error) {
// TODO render the error to the DOM
const h1 = document.createElement('h1');
h1.textContent = `Error: ${error?.message || error}`;
document.body.appendChild(h1);
Comment on lines +33 to +35

Choose a reason for hiding this comment

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

👍

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) => {

async function main() {
try {
const data = await requestData('https://xkcd.now.sh/?comic=latest')
renderImage(data);
} catch (error) {
Comment on lines +39 to +44

Choose a reason for hiding this comment

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

👍

renderError(error);
});
}
}

window.addEventListener('load', main);
79 changes: 52 additions & 27 deletions 3-UsingAPIs/Week2/assignment/ex2-pokemonApp/index.js
Original file line number Diff line number Diff line change
@@ -1,38 +1,63 @@
/*------------------------------------------------------------------------------
Full description at: https://github.com/HackYourFuture/Assignments/blob/main/3-UsingAPIs/Week2/README.md#exercise-2-gotta-catch-em-all
/* Exercise 2 – simple & functional */

const LIST_URL = 'https://pokeapi.co/api/v2/pokemon?limit=151';

Choose a reason for hiding this comment

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

TODO: Try to avoid global variables. Is there another place in this file where you can add the url?


async function fetchData(url) {
try {
const res = await fetch(url);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
} catch (err) {
console.error('Fetch error:', err);
throw err;
}
}
Comment on lines +6 to +14

Choose a reason for hiding this comment

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

👍


Complete the four functions provided in the starter `index.js` file:
async function fetchAndPopulatePokemons(select) {
select.disabled = true;
select.innerHTML = '<option>Loading…</option>';

`fetchData`: In the `fetchData` function, make use of `fetch` and its Promise
syntax in order to get the data from the public API. Errors (HTTP or network
errors) should be logged to the console.
const { results } = await fetchData(LIST_URL);

`fetchAndPopulatePokemons`: Use `fetchData()` to load the pokemon data from the
public API and populate the `<select>` element in the DOM.

`fetchImage`: Use `fetchData()` to fetch the selected image and update the
`<img>` element in the DOM.
select.innerHTML =

Choose a reason for hiding this comment

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

Better to use .textContent instead of .innerHTML to prevent HTML injections.

'<option value="">Choose a Pokémon…</option>' +
results
.map((p) => `<option value="${p.url}">${p.name}</option>`)
.join('');

`main`: The `main` function orchestrates the other functions. The `main`
function should be executed when the window has finished loading.
select.disabled = false;
}

Use async/await and try/catch to handle promises.
async function fetchImage(img, detailsUrl) {
if (!detailsUrl) return;
img.alt = 'Loading…'; img.src = '';

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
}
const d = await fetchData(detailsUrl);
const src =
d.sprites?.other?.['official-artwork']?.front_default ||
d.sprites?.front_default;

function fetchAndPopulatePokemons(/* TODO parameter(s) go here */) {
// TODO complete this function
if (src) { img.src = src; img.alt = d.name; }
else { img.alt = 'No image available'; }
}

function fetchImage(/* TODO parameter(s) go here */) {
// TODO complete this function
}
async function main() {
const btn = document.createElement('button');
btn.textContent = 'Get Pokémon!';
const select = document.createElement('select');
select.disabled = true;
const img = document.createElement('img');
img.style.maxWidth = '280px';

function main() {
// TODO complete this function
document.body.append(btn, select, img);

btn.addEventListener('click', async () => {
btn.disabled = true;
try { await fetchAndPopulatePokemons(select); }
catch { alert('Could not load list (see console).'); btn.disabled = false; }
});

select.addEventListener('change', (e) => fetchImage(img, e.target.value));
}

window.addEventListener('load', main);
Comment on lines 3 to +88

Choose a reason for hiding this comment

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

Good! Clean code that works end-to-end.

8 changes: 8 additions & 0 deletions 3-UsingAPIs/Week2/assignment/ex2-pokemonApp/style.css
Original file line number Diff line number Diff line change
@@ -1 +1,9 @@
/* add your styling here */
body {
display: flex;
flex-direction: column;
align-items: flex-start;
row-gap: 16px;
font-family: system-ui, Arial, sans-serif;
}
button, select { padding: .4rem .6rem; }
33 changes: 21 additions & 12 deletions 3-UsingAPIs/Week2/assignment/ex3-rollAnAce.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,30 @@ 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);
export async function rollDieUntil(desiredValue) {
let value;

Choose a reason for hiding this comment

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

Unnecessary let value. Could use scoped const inside the loop instead.


while (true) {
try {
value = await rollDie();
if (value === desiredValue) break;
} catch (err) {
throw err;

Choose a reason for hiding this comment

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

Error throw handling causes the function to reject, without retry. Perhaps use a console.error within the loop and throw error after a max number of attempts.

}
return value;
});
}

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);
}
Comment on lines +44 to +51

Choose a reason for hiding this comment

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

👍

}

// ! Do not change or remove the code below
Expand Down
20 changes: 13 additions & 7 deletions 3-UsingAPIs/Week2/assignment/ex4-diceRace.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,26 @@ 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 dicePromises = dice.map(() => rollDie());
return Promise.race(dicePromises);
Comment on lines +18 to +19

Choose a reason for hiding this comment

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

Good!

}

// 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.log('Rejected!', error.message);
}
Comment on lines +23 to +29

Choose a reason for hiding this comment

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

Nice!

}

// ! 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.
/*
Promise.race() stops at the first result, but the other dice keep rolling
because JavaScript promises can’t be canceled once started.
Comment on lines +38 to +39

Choose a reason for hiding this comment

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

👍

*/
13 changes: 8 additions & 5 deletions 3-UsingAPIs/Week2/assignment/ex5-vscDebug.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,17 @@ Full description at: https://github.com/HackYourFuture/Assignments/blob/main/3-U
Use the VSCode Debugger to fix the bugs
--------------------------------------------------------------- --------------*/
async function getData(url) {
const response = await fetch(url);
return response.json();
const res = await fetch(url);
if (!res.ok) throw new Error(`HTTP ${res.status}`);

Choose a reason for hiding this comment

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

👍

return res.json();
}

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}`);
console.log(`Birth: ${birth?.date}, ${birth.place.locationString}`);
if (death) {
console.log(`Death: ${death.date}, ${death.place.locationString}`);
}
Comment on lines +15 to +17

Choose a reason for hiding this comment

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

👍

}

function renderLaureates(laureates) {
Expand All @@ -20,7 +23,7 @@ function renderLaureates(laureates) {

async function fetchAndRender() {
try {
const laureates = getData(
const { laureates } = await getData(

Choose a reason for hiding this comment

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

👍

'http://api.nobelprize.org/2.0/laureates?birthCountry=Netherlands&format=json&csvLang=en'
);
renderLaureates(laureates);
Expand Down
8 changes: 5 additions & 3 deletions 3-UsingAPIs/Week2/assignment/ex6-browserDebug/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ function renderLaureate(ul, { knownName, birth, death }) {
const table = createAndAppend('table', li);
addTableRow(table, 'Name', knownName.en);
addTableRow(table, 'Birth', `${birth.date}, ${birth.place.locationString}`);
addTableRow(table, 'Death', `${death.date}, ${death.place.locationString}`);
if (death) {
addTableRow(table, 'Death', `${death.date}, ${death.place.locationString}`);
}
Comment on lines +34 to +36

Choose a reason for hiding this comment

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

👍

}

function renderLaureates(laureates) {
Expand All @@ -41,7 +43,7 @@ function renderLaureates(laureates) {

async function fetchAndRender() {
try {
const laureates = getData(
const {laureates} = await getData(

Choose a reason for hiding this comment

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

👍

'https://api.nobelprize.org/2.0/laureates?birthCountry=Netherlands&format=json&csvLang=en'
);
renderLaureates(laureates);
Expand All @@ -50,4 +52,4 @@ async function fetchAndRender() {
}
}

window.addEventListener('load', fetchAndRender);
window.addEventListener('load', fetchAndRender);
17 changes: 17 additions & 0 deletions 3-UsingAPIs/Week2/test-reports/ex1-programmerFun.report.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
*** Unit Test Error Report ***

PASS .dist/3-UsingAPIs/Week2/unit-tests/ex1-programmerFun.test.js (11.066 s)
api-wk2-ex1-programmerFun
✅ HTML should be syntactically valid (140 ms)
✅ should have all TODO comments removed (1 ms)
✅ should use `fetch()`
✅ should use async/wait
✅ should use try/catch (1 ms)

Test Suites: 1 passed, 1 total
Tests: 5 passed, 5 total
Snapshots: 0 total
Time: 11.574 s
Ran all test suites matching /C:\\Users\\khann\\IdeaProjects\\Assignments-cohort54\\.dist\\3-UsingAPIs\\Week2\\unit-tests\\ex1-programmerFun.test.js/i.
No linting errors detected.
No spelling errors detected.
17 changes: 17 additions & 0 deletions 3-UsingAPIs/Week2/test-reports/ex2-pokemonApp.report.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
*** Unit Test Error Report ***

PASS .dist/3-UsingAPIs/Week2/unit-tests/ex2-pokemonApp.test.js
api-wk2-ex2-pokemonApp
✅ HTML should be syntactically valid (147 ms)
✅ should have all TODO comments removed
✅ should use `fetch()`
✅ should use `await fetch()` (1 ms)
✅ should use try/catch

Test Suites: 1 passed, 1 total
Tests: 5 passed, 5 total
Snapshots: 0 total
Time: 3.341 s
Ran all test suites matching /C:\\Users\\khann\\IdeaProjects\\Assignments-cohort54\\.dist\\3-UsingAPIs\\Week2\\unit-tests\\ex2-pokemonApp.test.js/i.
No linting errors detected.
No spelling errors detected.
19 changes: 19 additions & 0 deletions 3-UsingAPIs/Week2/test-reports/ex3-rollAnAce.report.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
*** Unit Test Error Report ***

PASS .dist/3-UsingAPIs/Week2/unit-tests/ex3-rollAnAce.test.js
api-wk2-ex3-rollAnAce
✅ should have all TODO comments removed (1 ms)
✅ `rollDieUntil` should not contain unneeded console.log calls
✅ should not include a recursive call (1 ms)
✅ should use async/wait
✅ should use try/catch
✅ should resolve as soon as a die settles on an ACE (118 ms)
✅ should reject with an Error when a die rolls off the table (87 ms)

Test Suites: 1 passed, 1 total
Tests: 7 passed, 7 total
Snapshots: 0 total
Time: 0.929 s
Ran all test suites matching /C:\\Users\\khann\\IdeaProjects\\Assignments-cohort54\\.dist\\3-UsingAPIs\\Week2\\unit-tests\\ex3-rollAnAce.test.js/i.
No linting errors detected.
No spelling errors detected.
19 changes: 19 additions & 0 deletions 3-UsingAPIs/Week2/test-reports/ex4-diceRace.report.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
*** Unit Test Error Report ***

PASS .dist/3-UsingAPIs/Week2/unit-tests/ex4-diceRace.test.js
api-wk2-ex4-diceRace
✅ should exist and be executable (2 ms)
✅ should have all TODO comments removed (1 ms)
✅ `rollDice` should not contain unneeded console.log calls
✅ should use `dice.map()`
✅ should use `Promise.race()` (1 ms)
✅ should resolve as soon as a die settles successfully (118 ms)
✅ should reject with an Error as soon as a die rolls off the table (93 ms)

Test Suites: 1 passed, 1 total
Tests: 7 passed, 7 total
Snapshots: 0 total
Time: 0.887 s
Ran all test suites matching /C:\\Users\\khann\\IdeaProjects\\Assignments-cohort54\\.dist\\3-UsingAPIs\\Week2\\unit-tests\\ex4-diceRace.test.js/i.
No linting errors detected.
No spelling errors detected.
3 changes: 3 additions & 0 deletions 3-UsingAPIs/Week2/test-reports/ex5-vscDebug.report.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
A unit test file was not provided for this exercise.
No linting errors detected.
No spelling errors detected.
3 changes: 3 additions & 0 deletions 3-UsingAPIs/Week2/test-reports/ex6-browserDebug.report.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
A unit test file was not provided for this exercise.
No linting errors detected.
No spelling errors detected.