【问题标题】:How do I fetch and render images from an api?如何从 api 获取和渲染图像?
【发布时间】:2019-06-07 08:50:27
【问题描述】:

我有一个 api,它由一个对象组成,该对象包含嵌套在其中的 jpeg 链接数组。我想将每个图像渲染到 HTML 文档中,但是我得到一个错误

index.js:19 Uncaught (in promise) TypeError: Cannot read property 'forEach' 的未定义 在 addDogs (index.js:19) 在 index.js:30

我假设一旦我们使用链接获取对象,我们就会提取该对象内的 jpeg 链接数组并对其执行 forEach() 方法。但是似乎我错了,有人可以帮我吗?我的代码如下,包括 HTML 文档、JavaScript 代码和实际的 api。

HTML 文件

<!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"
  ]
}

【问题讨论】:

  • 您的内联&lt;img&gt; 元素看起来有点乱(没有&lt;table&gt;,没有&lt;td&gt;,没有属性引号,没有src 属性值的HTML 编码)。我会选择const img = document.createElement('img'); img.src = dog;。我还会创建一个&lt;td&gt; 并将图像附加到该

标签: javascript


【解决方案1】:

您似乎有一个并不真正需要的循环。您的 addDogs 函数应该看起来更像:

function addDogs(dogs) {
    dogs.message.forEach((dog) => addDog(dog))
}

这基本上翻译为“获取dogs 对象的消息属性并在其每个元素上调用addDog”。

此外,此时无需访问 addDog 中的 .message 属性,因为该函数中的 dog 参数已经是数组的一个元素。所以这可能变成:

tr.innerHTML = `<img src="${dog}">`

(请注意,我在它周围添加了引号,当@Phil 说您的 HTML 非常混乱时,他是对的)。

【讨论】:

  • OP 的 appDog 函数似乎需要一个具有 message 属性的对象,所以还有一些工作要做,也许是 .forEach(message =&gt; appDog({ message }))
  • 你说得对,我没有注意到这一点。我将编辑我的答案。
  • 我也注意到了很多其他问题(对问题发表了评论),不过你的回答没有问题
【解决方案2】:

您的函数addDog 似乎有错误;本质上,您希望它是一个带有 message 字段的对象,但它只是一个字符串,因此要使其正常工作,您可能只需要修复您使用它的方式,例如:


function addDog(imgUrl) {
    const tr = document.createElement('tr')
    tr.innerHTML = `<img src = ${imgUrl} >`
    dogsContainer.append(tr)
}

这是因为您的有效负载有一组图像 url,但您似乎认为它们是对象。

编辑:

实际上,您的addDogs 函数似乎也有错误。 我建议您将它们合并为:

function addDogs(dogs) {
    dogs.message.forEach((img) => function(img){
        const tr = document.createElement('tr')
        tr.innerHTML = `<img src = ${img} >`
        dogsContainer.append(tr)
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-11
    • 1970-01-01
    • 1970-01-01
    • 2019-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多