diff --git a/.test-summary/TEST_SUMMARY.md b/.test-summary/TEST_SUMMARY.md
new file mode 100644
index 000000000..a5f0d5725
--- /dev/null
+++ b/.test-summary/TEST_SUMMARY.md
@@ -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 | - | - | ✓ |
diff --git a/.vscode/settings.json b/.vscode/settings.json
index f7d6e29e1..a455d2bb5 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -16,5 +16,6 @@
"editor.bracketPairColorization.enabled": true,
"editor.guides.bracketPairs": true,
"editor.guides.highlightActiveIndentation": true,
- "editor.guides.bracketPairsHorizontal": "active"
+ "editor.guides.bracketPairsHorizontal": "active",
+ "liveServer.settings.port": 5501
}
diff --git a/3-UsingAPIs/Week2/assignment/ex1-programmerFun/index.js b/3-UsingAPIs/Week2/assignment/ex1-programmerFun/index.js
index a99ca177b..02afd8d37 100644
--- a/3-UsingAPIs/Week2/assignment/ex1-programmerFun/index.js
+++ b/3-UsingAPIs/Week2/assignment/ex1-programmerFun/index.js
@@ -1,44 +1,36 @@
-/*------------------------------------------------------------------------------
-Full description at: https://github.com/HackYourFuture/Assignments/blob/main/3-UsingAPIs/Week2/README.md#exercise-1-programmer-fun
-
-1. Complete the function `requestData()` using `fetch()` to make a request to
- the url passed to it as an argument. The function should return a promise.
- Make sure that the promise is rejected in case of HTTP or network errors.
-2. Notice that the function `main()` calls `requestData()`, passing it the url
- `https://xkcd.now.sh/?comic=latest`. Try and run the code in the browser and
- open the browser's console to inspect the data returned from the request.
-3. Next, complete the function `renderImage()` to render an image as an ` `
- element appended to the document's body, using the data returned from the API.
-4. Complete the function `renderError()` to render any errors as an `
`
- element appended to the document's body.
-5. Refactor the `main()` function to use `async/await`.
-6. Test error handling, for instance, by temporarily changing the `.sh` in the
- 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()`
+ return fetch(url)
+ .then((response) => {
+ if (!response.ok) {
+ throw new Error(`HTTP error! Status: ${response.status}`);
+ }
+ return response.json();
+ });
}
function renderImage(data) {
- // TODO render the image to the DOM
- console.log(data);
+ const img = document.createElement('img');
+ img.src = data.img;
+ img.alt = data.alt;
+ img.title = data.title;
+ img.style.maxWidth = '100%';
+ document.body.appendChild(img);
}
function renderError(error) {
- // TODO render the error to the DOM
- console.log(error);
+ const errorElement = document.createElement('h1');
+ errorElement.textContent = `Error: ${error.message}`;
+ errorElement.style.color = 'red';
+ document.body.appendChild(errorElement);
}
-// 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);
diff --git a/3-UsingAPIs/Week2/assignment/ex2-pokemonApp/index.js b/3-UsingAPIs/Week2/assignment/ex2-pokemonApp/index.js
index 262113997..88a1b108b 100644
--- a/3-UsingAPIs/Week2/assignment/ex2-pokemonApp/index.js
+++ b/3-UsingAPIs/Week2/assignment/ex2-pokemonApp/index.js
@@ -1,38 +1,61 @@
-/*------------------------------------------------------------------------------
-Full description at: https://github.com/HackYourFuture/Assignments/blob/main/3-UsingAPIs/Week2/README.md#exercise-2-gotta-catch-em-all
-
-Complete the four functions provided in the starter `index.js` file:
-
-`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.
-
-`fetchAndPopulatePokemons`: Use `fetchData()` to load the pokemon data from the
- public API and populate the `` element in the DOM.
-
-`fetchImage`: Use `fetchData()` to fetch the selected image and update the
- ` ` element in the DOM.
-
-`main`: The `main` function orchestrates the other functions. The `main`
- function should be executed when the window has finished loading.
-
-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}`);
+ }
+ return await response.json();
+ } catch (error) {
+ console.error('Fetch error:', error);
+ throw error;
+ }
}
-function fetchAndPopulatePokemons(/* TODO parameter(s) go here */) {
- // TODO complete this function
+async function fetchAndPopulatePokemons(selectElement) {
+ const url = 'https://pokeapi.co/api/v2/pokemon?limit=150';
+ try {
+ const data = await fetchData(url);
+ data.results.forEach(pokemon => {
+ const option = document.createElement('option');
+ option.value = pokemon.url;
+ option.textContent = capitalize(pokemon.name);
+ selectElement.appendChild(option);
+ });
+ } catch (error) {
+ console.error('Error populating Pokémon list:', error);
+ }
}
-function fetchImage(/* TODO parameter(s) go here */) {
- // TODO complete this function
+async function fetchImage(url, imgElement) {
+ try {
+ const data = await fetchData(url);
+ const imageUrl = data.sprites.front_default;
+ imgElement.src = imageUrl;
+ imgElement.alt = data.name;
+ } catch (error) {
+ console.error('Error fetching image:', error);
+ }
+}
+function capitalize(string) {
+ return string.charAt(0).toUpperCase() + string.slice(1);
}
-function main() {
- // TODO complete this function
+async function main() {
+ const select = document.createElement('select');
+ const img = document.createElement('img');
+ img.alt = 'Select a Pokémon to see its image';
+ img.style.marginTop = '1rem';
+
+ document.body.appendChild(select);
+ document.body.appendChild(img);
+
+ await fetchAndPopulatePokemons(select);
+
+ select.addEventListener('change', () => {
+ const url = select.value;
+ if (url) {
+ fetchImage(url, img);
+ }
+ });
}
+window.addEventListener('load', main);
\ No newline at end of file
diff --git a/3-UsingAPIs/Week2/assignment/ex3-rollAnAce.js b/3-UsingAPIs/Week2/assignment/ex3-rollAnAce.js
index 861b31047..48062ce1c 100644
--- a/3-UsingAPIs/Week2/assignment/ex3-rollAnAce.js
+++ b/3-UsingAPIs/Week2/assignment/ex3-rollAnAce.js
@@ -1,14 +1,3 @@
-/*------------------------------------------------------------------------------
-Full description at: https://github.com/HackYourFuture/Assignments/blob/main/3-UsingAPIs/Week2/README.md#exercise-3-roll-an-ace
-
-1. Run the unmodified exercise and observe that it works as advertised. Observe
- that the die must be thrown an indeterminate number of times until we get an
- ACE or until it rolls off the table.
-2. Now, rewrite the body of the `rollDieUntil()` function using async/await and
- without using recursion. Hint: a `while` loop may come handy.
-3. Refactor the function `main()` to use async/await and try/catch.
-------------------------------------------------------------------------------*/
-// ! Do not change or remove the next two lines
import { rollDie } from '../../helpers/pokerDiceRoller.js';
/** @import {DieFace} from "../../helpers/pokerDiceRoller.js" */
@@ -17,24 +6,26 @@ import { rollDie } from '../../helpers/pokerDiceRoller.js';
* @param {DieFace} desiredValue
* @returns {Promise}
*/
-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 result;
+
+ while (true) {
+ result = await rollDie();
+ if (result === desiredValue) {
+ return result;
}
- 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
if (process.env.NODE_ENV !== 'test') {
main();
}
diff --git a/3-UsingAPIs/Week2/assignment/ex4-diceRace.js b/3-UsingAPIs/Week2/assignment/ex4-diceRace.js
index ddff3242c..9f6b572ac 100644
--- a/3-UsingAPIs/Week2/assignment/ex4-diceRace.js
+++ b/3-UsingAPIs/Week2/assignment/ex4-diceRace.js
@@ -1,29 +1,23 @@
-/*------------------------------------------------------------------------------
-Full description at: https://github.com/HackYourFuture/Assignments/blob/main/3-UsingAPIs/Week2/README.md#exercise-4-dice-race
-
-1. Complete the function `rollDice()` by using `.map()` on the `dice` array
- to create an array of promises for use with `Promise.race()`.
-2. Refactor the function `main()` using async/await and try/catch.
-3. Once you got this working, you may observe that some dice continue rolling
- for some undetermined time after the promise returned by `Promise.race()`
- resolves. Do you know why? Add your answer as a comment to the bottom of the
- file.
-------------------------------------------------------------------------------*/
-// ! Do not remove these lines
import { rollDie } from '../../helpers/pokerDiceRoller.js';
/** @import {DieFace} from "../../helpers/pokerDiceRoller.js" */
-export function rollDice() {
+/**
+ * Rolls five dice and waits for the first one to finish.
+ * @returns {Promise} The result of the first die roll to finish.
+ */
+export async 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 promises = dice.map((dieNumber) => rollDie(dieNumber));
+ return Promise.race(promises);
}
-// 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);
+ }
}
// ! Do not change or remove the code below
@@ -31,4 +25,9 @@ if (process.env.NODE_ENV !== 'test') {
main();
}
-// TODO Replace this comment by your explanation that was asked for in the assignment description.
+
+// We are using Promise.race() here in line 11. The logic if it is just to wait for the first promise in the array to resolve.
+// No metter either successfully or unsuccessfully. Once the first promise resolves, it "wins" and returns its result.
+// However, this does not mean that the rest of the promises in the array will stop.
+// No way to stop them as we found in the previous week.
+// So, Promise.race() does not cancel other promises, it just does not wait for them to resolve after one of them has already resolved.
diff --git a/3-UsingAPIs/Week2/assignment/ex5-vscDebug.js b/3-UsingAPIs/Week2/assignment/ex5-vscDebug.js
index a65448e57..fa198c300 100644
--- a/3-UsingAPIs/Week2/assignment/ex5-vscDebug.js
+++ b/3-UsingAPIs/Week2/assignment/ex5-vscDebug.js
@@ -10,8 +10,10 @@ 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}`);
+ console.log(`Birth: ${birth.date}, ${birth.place.locationString.en}`);
+ if (death) {
+ console.log(`Death: ${death.date}, ${death.place.locationString.en}`);
+ }
}
function renderLaureates(laureates) {
@@ -20,12 +22,13 @@ function renderLaureates(laureates) {
async function fetchAndRender() {
try {
- const laureates = getData(
+ const { laureates } = await getData(
'http://api.nobelprize.org/2.0/laureates?birthCountry=Netherlands&format=json&csvLang=en'
);
- renderLaureates(laureates);
+ renderLaureates(laureates);
} catch (err) {
console.error(`Something went wrong: ${err.message}`);
+ console.log(err.stack);
}
}
diff --git a/3-UsingAPIs/Week2/assignment/ex6-browserDebug/index.js b/3-UsingAPIs/Week2/assignment/ex6-browserDebug/index.js
index 91e0402be..76d626de2 100644
--- a/3-UsingAPIs/Week2/assignment/ex6-browserDebug/index.js
+++ b/3-UsingAPIs/Week2/assignment/ex6-browserDebug/index.js
@@ -1,7 +1,3 @@
-/*
-Full description at:https://github.com/HackYourFuture/Assignments/blob/main/3-UsingAPIs/Week2/README.md#exercise-6-using-the-browser-debugger
-*/
-
async function getData(url) {
const response = await fetch(url);
return response.json();
@@ -30,8 +26,12 @@ function renderLaureate(ul, { knownName, birth, death }) {
const li = createAndAppend('li', ul);
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}`);
+
+ const birthInfo = birth ? `${birth.date}, ${birth.place.locationString.en}` : 'Unknown';
+ addTableRow(table, 'Birth', birthInfo);
+
+ const deathInfo = death ? `${death.date}, ${death.place.locationString.en}` : 'Unknown';
+ addTableRow(table, 'Death', deathInfo);
}
function renderLaureates(laureates) {
@@ -41,10 +41,16 @@ function renderLaureates(laureates) {
async function fetchAndRender() {
try {
- const laureates = getData(
+ const data = await getData(
'https://api.nobelprize.org/2.0/laureates?birthCountry=Netherlands&format=json&csvLang=en'
);
- renderLaureates(laureates);
+ const laureates = data.laureates;
+
+ if (laureates) {
+ renderLaureates(laureates);
+ } else {
+ console.error('No laureates data available');
+ }
} catch (err) {
console.error(`Something went wrong: ${err.message}`);
}
diff --git a/3-UsingAPIs/Week2/test-reports/ex1-programmerFun.report.txt b/3-UsingAPIs/Week2/test-reports/ex1-programmerFun.report.txt
new file mode 100644
index 000000000..c8175cf3f
--- /dev/null
+++ b/3-UsingAPIs/Week2/test-reports/ex1-programmerFun.report.txt
@@ -0,0 +1,17 @@
+*** Unit Test Error Report ***
+
+ PASS .dist/3-UsingAPIs/Week2/unit-tests/ex1-programmerFun.test.js (11.957 s)
+ api-wk2-ex1-programmerFun
+ ✅ HTML should be syntactically valid (135 ms)
+ ✅ should have all TODO comments removed
+ ✅ should use `fetch()`
+ ✅ should use async/wait (1 ms)
+ ✅ should use try/catch
+
+Test Suites: 1 passed, 1 total
+Tests: 5 passed, 5 total
+Snapshots: 0 total
+Time: 12.465 s
+Ran all test suites matching /\/Users\/hackmyfuture\/HYF\/HYF-Assignments-cohort52\/.dist\/3-UsingAPIs\/Week2\/unit-tests\/ex1-programmerFun.test.js/i.
+No linting errors detected.
+No spelling errors detected.
diff --git a/3-UsingAPIs/Week2/test-reports/ex2-pokemonApp.report.txt b/3-UsingAPIs/Week2/test-reports/ex2-pokemonApp.report.txt
new file mode 100644
index 000000000..9c7339985
--- /dev/null
+++ b/3-UsingAPIs/Week2/test-reports/ex2-pokemonApp.report.txt
@@ -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 (136 ms)
+ ✅ should have all TODO comments removed
+ ✅ should use `fetch()`
+ ✅ should use `await fetch()`
+ ✅ should use try/catch
+
+Test Suites: 1 passed, 1 total
+Tests: 5 passed, 5 total
+Snapshots: 0 total
+Time: 2.594 s
+Ran all test suites matching /\/Users\/hackmyfuture\/HYF\/HYF-Assignments-cohort52\/.dist\/3-UsingAPIs\/Week2\/unit-tests\/ex2-pokemonApp.test.js/i.
+No linting errors detected.
+No spelling errors detected.
diff --git a/3-UsingAPIs/Week2/test-reports/ex3-rollAnAce.report.txt b/3-UsingAPIs/Week2/test-reports/ex3-rollAnAce.report.txt
new file mode 100644
index 000000000..67edc071b
--- /dev/null
+++ b/3-UsingAPIs/Week2/test-reports/ex3-rollAnAce.report.txt
@@ -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 (2 ms)
+ ✅ `rollDieUntil` should not contain unneeded console.log calls
+ ✅ should not include a recursive call
+ ✅ should use async/wait
+ ✅ should use try/catch
+ ✅ should resolve as soon as a die settles on an ACE (22 ms)
+ ✅ should reject with an Error when a die rolls off the table (12 ms)
+
+Test Suites: 1 passed, 1 total
+Tests: 7 passed, 7 total
+Snapshots: 0 total
+Time: 0.522 s
+Ran all test suites matching /\/Users\/hackmyfuture\/HYF\/HYF-Assignments-cohort52\/.dist\/3-UsingAPIs\/Week2\/unit-tests\/ex3-rollAnAce.test.js/i.
+No linting errors detected.
+No spelling errors detected.
diff --git a/3-UsingAPIs/Week2/test-reports/ex4-diceRace.report.txt b/3-UsingAPIs/Week2/test-reports/ex4-diceRace.report.txt
new file mode 100644
index 000000000..db213eb81
--- /dev/null
+++ b/3-UsingAPIs/Week2/test-reports/ex4-diceRace.report.txt
@@ -0,0 +1,23 @@
+*** 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 (2 ms)
+ ✅ `rollDice` should not contain unneeded console.log calls (1 ms)
+ ✅ should use `dice.map()`
+ ✅ should use `Promise.race()` (1 ms)
+ ✅ should resolve as soon as a die settles successfully (9 ms)
+ ✅ should reject with an Error as soon as a die rolls off the table (27 ms)
+
+Test Suites: 1 passed, 1 total
+Tests: 7 passed, 7 total
+Snapshots: 0 total
+Time: 1.656 s
+Ran all test suites matching /\/Users\/hackmyfuture\/HYF\/HYF-Assignments-cohort52\/.dist\/3-UsingAPIs\/Week2\/unit-tests\/ex4-diceRace.test.js/i.
+No linting errors detected.
+
+
+*** Spell Checker Report ***
+
+3-UsingAPIs/Week2/assignment/ex4-diceRace.js:30:7 - Unknown word (metter)
diff --git a/3-UsingAPIs/Week2/test-reports/ex5-vscDebug.report.txt b/3-UsingAPIs/Week2/test-reports/ex5-vscDebug.report.txt
new file mode 100644
index 000000000..d985f405c
--- /dev/null
+++ b/3-UsingAPIs/Week2/test-reports/ex5-vscDebug.report.txt
@@ -0,0 +1,3 @@
+A unit test file was not provided for this exercise.
+No linting errors detected.
+No spelling errors detected.
diff --git a/3-UsingAPIs/Week2/test-reports/ex6-browserDebug.report.txt b/3-UsingAPIs/Week2/test-reports/ex6-browserDebug.report.txt
new file mode 100644
index 000000000..d985f405c
--- /dev/null
+++ b/3-UsingAPIs/Week2/test-reports/ex6-browserDebug.report.txt
@@ -0,0 +1,3 @@
+A unit test file was not provided for this exercise.
+No linting errors detected.
+No spelling errors detected.