Reputation:
I have an api which consists of an object that contains an array of jpeg links nested inside them. I wanted to render each image into the HTML document however I get an error of
index.js:19 Uncaught (in promise) TypeError: Cannot read property 'forEach' of undefined at addDogs (index.js:19) at index.js:30
I'm assuming once we fetch the object using the link, we extract the array of jpeg links inside that object and do a forEach() method on it. However it seem's I'm wrong, could someone help me out please? My code is below, which includes the HTML document, JavaScript code and the actual api.
HTML File
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Intro to AJAX Practice Tasks</title>
<script src="src/index.js" charset="utf-8"></script>
</head>
<body>
<h1>Dog CEO</h1>
<div id="dog-image-container">
<!-- images here -->
</div>
<hr>
<label for="select-breed">Filter Breeds That Start with:</label>
<select id="breed-dropdown" name="select-breed">
<option value="a">a</option>
<option value="b">b</option>
<option value="c">c</option>
<option value="d">d</option>
</select>
<ul id="dog-breeds">
</ul>
</body>
</html>
JavaScript
const imgUrl = "https://dog.ceo/api/breeds/image/random/4"
const dogsContainer = document.getElementById("dog-breeds")
function addDog(dog) {
const tr = document.createElement('tr')
tr.innerHTML = `<img src = ${dog.message} >`
dogsContainer.append(tr)
}
function addDogs(dogs) {
for (const key in dogs) {
const dogImages = dogs[key]
dogImages.message.forEach((dog) => addDog(dog))
}
}
function getDogs() {
return fetch(imgUrl)
.then((response) => response.json())
}
getDogs()
.then((dogs) => addDogs(dogs))
API(JSON)
{
"status": "success",
"message": [
"https://images.dog.ceo/breeds/komondor/n02105505_4290.jpg",
"https://images.dog.ceo/breeds/schipperke/n02104365_8190.jpg",
"https://images.dog.ceo/breeds/entlebucher/n02108000_3306.jpg",
"https://images.dog.ceo/breeds/keeshond/n02112350_6861.jpg"
]
}
Upvotes: 0
Views: 2956
Reputation: 1657
It seems you have an error in your function addDog
; essentially you are expecting it to be an object with a message
field however it is just a string so to get it to work you might just need to fix the way you are using it, for example:
function addDog(imgUrl) {
const tr = document.createElement('tr')
tr.innerHTML = `<img src = ${imgUrl} >`
dogsContainer.append(tr)
}
This is beacuse your payload has an array of image urls but you seem to have assumed that they are objects.
EDIT:
Actually you seem to have a mistake in your addDogs
function as well.
I'd recommend you merge them into something like:
function addDogs(dogs) {
dogs.message.forEach((img) => function(img){
const tr = document.createElement('tr')
tr.innerHTML = `<img src = ${img} >`
dogsContainer.append(tr)
}
}
Upvotes: 0
Reputation: 4383
You seem to be having a loop that's not really needed. Your addDogs
function should look more like:
function addDogs(dogs) {
dogs.message.forEach((dog) => addDog(dog))
}
Which basically translates to "get the message property of the dogs
object and call addDog on each of its elements".
Also, at that point there's no need to access the .message property in addDog, since the dog parameter in that function will already be an element of the array. So that could become:
tr.innerHTML = `<img src="${dog}">`
(Notice that I added quotes around it, and that @Phil is right when he says that your HTML is quite messy).
Upvotes: 1