I am trying to pull some data from this website by referring to their documentation at /dog-api/documentation/
I am trying to retrieve the list of dog breeds and create a list. I am using javaScript's "fetch"
let dog_list = [];
fetch('/api/breeds/list/all')
.then(response => {
if (response.ok) {
return response.json();
} else {
throw new Error(response.statusText);
}
})
.then(data => dog_list = data.message)
const container = document.getElementById("container");
for (dog in dog_list) {
let li = document.createElement("li");
let node = document.createTextNode(dog);
li.appendChild(node);
container.appendChild(li);
}
<!DOCTYPE html>
<html lang="en">
<head>
<title>Dog Breed List</title>
</head>
<body>
<ul id="container"></ul>
<script src="dog_breed.js"></script>
</body>
</html>
I am trying to pull some data from this website by referring to their documentation at https://dog.ceo/dog-api/documentation/
I am trying to retrieve the list of dog breeds and create a list. I am using javaScript's "fetch"
let dog_list = [];
fetch('https://dog.ceo/api/breeds/list/all')
.then(response => {
if (response.ok) {
return response.json();
} else {
throw new Error(response.statusText);
}
})
.then(data => dog_list = data.message)
const container = document.getElementById("container");
for (dog in dog_list) {
let li = document.createElement("li");
let node = document.createTextNode(dog);
li.appendChild(node);
container.appendChild(li);
}
<!DOCTYPE html>
<html lang="en">
<head>
<title>Dog Breed List</title>
</head>
<body>
<ul id="container"></ul>
<script src="dog_breed.js"></script>
</body>
</html>
I am having issues at the second "then" where I have no idea on how to convert the json object into array and display them as
- dog1
- dog2
- dog3
- 2 Possible duplicate of How do I return the response from an asynchronous call? – adiga Commented Mar 10, 2019 at 17:22
-
Move the
for
loop inside the callback..then(data => { dog_list = data.message; const container = document.getElementById("container"); for (dog in dog_list) {....} })
– adiga Commented Mar 10, 2019 at 17:23 - Your loop runs before the dogs are fetched.. – Mr. Alien Commented Mar 10, 2019 at 17:24
3 Answers
Reset to default 5Just construct you li
inside the callback where you create dog_list...
Something like this...
let dog_list = [];
const container = document.getElementById("container");
fetch('https://dog.ceo/api/breeds/list/all')
.then(response => {
if (response.ok) {
return response.json();
} else {
throw new Error(response.statusText);
}
})
.then(data => {
dog_list = data.message;
for (dog in dog_list) {
let li = document.createElement("li");
let node = document.createTextNode(dog);
li.appendChild(node);
container.appendChild(li);
}
});
Why do you need to construct resulting DOM structure inside promise handler?
Because the plete
fetch(/*...*/).then(/*...*/).then(/*...*)
block will be executed asynchronously
Without waiting for that code to plete, mainline ('global') code will continue its execution from the line after that, which in your case is getting the container and start adding li
elements. Problem is that at this point the processing of the response from the fetch call will not even start (even if the fetch has been executed and results have been returned) and consequently dog_list
will be empty.
Since the callback in .then
is asynchronous, you can populate the list inside the .then
callback otherwise dog_list
will still be an empty array the time when the loop runs:
fetch('https://dog.ceo/api/breeds/list/all')
.then(response => {
if (response.ok) {
return response.json();
} else {
throw new Error(response.statusText);
}
})
.then(data => populate(data.message));
function populate(dog_list){
const container = document.getElementById("container");
for (dog in dog_list) {
let li = document.createElement("li");
let node = document.createTextNode(dog);
li.appendChild(node);
container.appendChild(li);
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<title>Dog Breed List</title>
</head>
<body>
<ul id="container"></ul>
</body>
</html>
You could also try the same with async
and await
.
Please have a look below.
const url = 'https://dog.ceo/api/breeds/list/all';
async function Main() {
const dog_data = await getDogData(url).catch(catchError);
const dog_list = dog_data.message;
const container = document.getElementById("container");
for (dog in dog_list) {
const node = createHTMLElement('li', dog);
container.appendChild(node);
}
}
function catchError(err) {
console.log('Error ', err);
}
function createHTMLElement(_node, data) {
let li = document.createElement("li");
li.textContent = dog;
return li;
}
async function getDogData(_url) {
const response = await fetch(_url);
return await response.json();
}
Main();
<!DOCTYPE html>
<html lang="en">
<head>
<title>Dog Breed List</title>
</head>
<body>
<ul id="container"></ul>
</body>
</html>