【问题标题】:TypeError: Cannot read property 'value' of undefined Ajax call on JSONTypeError:无法读取 JSON 上未定义 Ajax 调用的属性“值”
【发布时间】:2018-10-07 20:44:26
【问题描述】:

在我下面的 ajax 调用中,我从 JSON 文件调用内容,但是,我得到下面列出的错误。

TypeError:无法读取未定义的属性“image_url” 在 myscripts.js:26

如果我使用 (realestate)[0] 定位 JSON 数据的第一部分,它不会给出错误,但是如果我使用 (realestate)[1] 定位第二部分它会给出错误。

我已经为此坐了几个小时,但还没有弄清楚,有人可以解释发生了什么以及为什么它无法识别属性类型吗?

window.onload = function(){
  function get (url){
    return new Promise(function(resolve, reject){
      var xhttp = new XMLHttpRequest();
      xhttp.open('GET', url, true);
      xhttp.onload = function(){
        if (xhttp.status == 200){
          resolve(JSON.parse(xhttp.response));
        } else{
          reject(xhttp.statusText);
        }
      };
      xhttp.onerror = function (){
        reject(xhttp.statusText);
      };
      xhttp.send();
    });
  }

  var promise = get('url');
  promise.then(function(realestate){

    for (var key in realestate) {
      for (var i = 0; i < realestate[key].length; i++) {
        var image_url   = realestate[Object.keys(realestate)[1]][i].image_url;
        var name        = realestate[Object.keys(realestate)[1]][i].name;
        var price       = realestate[Object.keys(realestate)[1]][i].price;
        var squareFt    = realestate[Object.keys(realestate)[1]][i].squareFt;
        var collection2 = document.createElement('div');
        collection2.className = 'house';
        collection2.innerHTML =
          `<img src="${image_url}">
<p>${name} <span>${price}</span></p>
<p>${squareFt}</p>
`;
        document.getElementById('sd-collection').appendChild(collection2);      
      }
    }

  }).catch(function(error){
    console.log(error);
  });
};

JSON文件内容

{ 
        "40_collection": [
            {"image_url":"material/images/model-fpo.jpg","name":"Chealse 1","price":"$900,000","squareFt":"4343 SQ. FT"},
            {"image_url":"material/images/model-fpo.jpg","name":"Chealse 2","price":"$800,000","squareFt":"4545 SQ. FT"},
            {"image_url":"material/images/model-fpo.jpg","name":"Chealse 3","price":"$700,000","squareFt":"1238 SQ. FT"},
            {"image_url":"material/images/model-fpo.jpg","name":"Chealse 4","price":"$600,000","squareFt":"1257 SQ. FT"},
            {"image_url":"material/images/model-fpo.jpg","name":"Chealse 5","price":"$200,000","squareFt":"2120 SQ. FT"},
            {"image_url":"material/images/model-fpo.jpg","name":"Chealse 6","price":"$805,000","squareFt":"7878 SQ. FT"},
            {"image_url":"material/images/model-fpo.jpg","name":"Chealse 7","price":"$620,000","squareFt":"9898 SQ. FT"},
            {"image_url":"material/images/model-fpo.jpg","name":"Chealse 8","price":"$150,000","squareFt":"8989 SQ. FT"},
            {"image_url":"material/images/model-fpo.jpg","name":"Chealse 9","price":"$600,000","squareFt":"1212 SQ. FT"},
            {"image_url":"material/images/model-fpo.jpg","name":"Chealse 10","price":"$100,000","squareFt":"2323 SQ. FT"}
            ],
        "sd_collection": [
            {"image_url":"material/images/model-fpo.jpg","name":"Chealse 11","price":"$500,000","squareFt":"4321 SQ. FT"},
            {"image_url":"material/images/model-fpo.jpg","name":"Chealse 12","price":"$700,000","squareFt":"7824 SQ. FT"},
            {"image_url":"material/images/model-fpo.jpg","name":"Chealse 13","price":"$600,000","squareFt":"7812 SQ. FT"},
            {"image_url":"material/images/model-fpo.jpg","name":"Chealse 14","price":"$950,000","squareFt":"9794 SQ. FT"},
            {"image_url":"material/images/model-fpo.jpg","name":"Chealse 15","price":"$350,000","squareFt":"1234 SQ. FT"}
    ]
}

【问题讨论】:

  • 为什么不直接使用fetch 而不是一个hacky 的自定义get 函数?
  • 到目前为止我还没有使用 fetch,在这个例子中,当我遇到当前的问题时,我实际上是在尝试习惯使用 Promise 和 ajax 调用的想法。

标签: javascript ajax typeerror


【解决方案1】:

您正在遍历每个键并遍历realestate[key] 中的每个元素,但是您总是尝试访问second 数组sd_collection 中的ith 元素,它只有5个元素。第一个数组有更多元素;所以一旦i 达到5,访问第二个数组中[5] 的索引就会出错。

改用数组方法会好得多。你看起来没有使用keys,所以使用Object.values

const realestate = { 
  "40_collection": [
    {"image_url":"material/images/model-fpo.jpg","name":"Chealse 1","price":"$900,000","squareFt":"4343 SQ. FT"},
    {"image_url":"material/images/model-fpo.jpg","name":"Chealse 2","price":"$800,000","squareFt":"4545 SQ. FT"},
    {"image_url":"material/images/model-fpo.jpg","name":"Chealse 3","price":"$700,000","squareFt":"1238 SQ. FT"},
    {"image_url":"material/images/model-fpo.jpg","name":"Chealse 4","price":"$600,000","squareFt":"1257 SQ. FT"},
    {"image_url":"material/images/model-fpo.jpg","name":"Chealse 5","price":"$200,000","squareFt":"2120 SQ. FT"},
    {"image_url":"material/images/model-fpo.jpg","name":"Chealse 6","price":"$805,000","squareFt":"7878 SQ. FT"},
    {"image_url":"material/images/model-fpo.jpg","name":"Chealse 7","price":"$620,000","squareFt":"9898 SQ. FT"},
    {"image_url":"material/images/model-fpo.jpg","name":"Chealse 8","price":"$150,000","squareFt":"8989 SQ. FT"},
    {"image_url":"material/images/model-fpo.jpg","name":"Chealse 9","price":"$600,000","squareFt":"1212 SQ. FT"},
    {"image_url":"material/images/model-fpo.jpg","name":"Chealse 10","price":"$100,000","squareFt":"2323 SQ. FT"}
  ],
  "sd_collection": [
    {"image_url":"material/images/model-fpo.jpg","name":"Chealse 11","price":"$500,000","squareFt":"4321 SQ. FT"},
    {"image_url":"material/images/model-fpo.jpg","name":"Chealse 12","price":"$700,000","squareFt":"7824 SQ. FT"},
    {"image_url":"material/images/model-fpo.jpg","name":"Chealse 13","price":"$600,000","squareFt":"7812 SQ. FT"},
    {"image_url":"material/images/model-fpo.jpg","name":"Chealse 14","price":"$950,000","squareFt":"9794 SQ. FT"},
    {"image_url":"material/images/model-fpo.jpg","name":"Chealse 15","price":"$350,000","squareFt":"1234 SQ. FT"}
  ]
};

Object.values(realestate).forEach((arr) => {
  arr.forEach(({ image_url, name, price, squareFt }) => {
    var collection2 = document.createElement('div');
    collection2.className = 'house';
    collection2.innerHTML =
      `<img src="${image_url}">
<p>${name} <span>${price}</span></p>
<p>${squareFt}</p>
`;
    document.getElementById('sd-collection').appendChild(collection2);      
  })
});
&lt;div id="sd-collection"&gt;&lt;/div&gt;

或者,如果您只想遍历第二个集合:

const realestate = { 
"40_collection": [
  {"image_url":"material/images/model-fpo.jpg","name":"Chealse 1","price":"$900,000","squareFt":"4343 SQ. FT"},
  {"image_url":"material/images/model-fpo.jpg","name":"Chealse 2","price":"$800,000","squareFt":"4545 SQ. FT"},
  {"image_url":"material/images/model-fpo.jpg","name":"Chealse 3","price":"$700,000","squareFt":"1238 SQ. FT"},
  {"image_url":"material/images/model-fpo.jpg","name":"Chealse 4","price":"$600,000","squareFt":"1257 SQ. FT"},
  {"image_url":"material/images/model-fpo.jpg","name":"Chealse 5","price":"$200,000","squareFt":"2120 SQ. FT"},
  {"image_url":"material/images/model-fpo.jpg","name":"Chealse 6","price":"$805,000","squareFt":"7878 SQ. FT"},
  {"image_url":"material/images/model-fpo.jpg","name":"Chealse 7","price":"$620,000","squareFt":"9898 SQ. FT"},
  {"image_url":"material/images/model-fpo.jpg","name":"Chealse 8","price":"$150,000","squareFt":"8989 SQ. FT"},
  {"image_url":"material/images/model-fpo.jpg","name":"Chealse 9","price":"$600,000","squareFt":"1212 SQ. FT"},
  {"image_url":"material/images/model-fpo.jpg","name":"Chealse 10","price":"$100,000","squareFt":"2323 SQ. FT"}
],
"sd_collection": [
  {"image_url":"material/images/model-fpo.jpg","name":"Chealse 11","price":"$500,000","squareFt":"4321 SQ. FT"},
  {"image_url":"material/images/model-fpo.jpg","name":"Chealse 12","price":"$700,000","squareFt":"7824 SQ. FT"},
  {"image_url":"material/images/model-fpo.jpg","name":"Chealse 13","price":"$600,000","squareFt":"7812 SQ. FT"},
  {"image_url":"material/images/model-fpo.jpg","name":"Chealse 14","price":"$950,000","squareFt":"9794 SQ. FT"},
  {"image_url":"material/images/model-fpo.jpg","name":"Chealse 15","price":"$350,000","squareFt":"1234 SQ. FT"}
]
};


realestate.sd_collection.forEach(({ image_url, name, price, squareFt }) => {
  var collection2 = document.createElement('div');
  collection2.className = 'house';
  collection2.innerHTML =
    `<img src="${image_url}">
<p>${name} <span>${price}</span></p>
<p>${squareFt}</p>
`;
  document.getElementById('sd-collection').appendChild(collection2);      
});
&lt;div id="sd-collection"&gt;&lt;/div&gt;

【讨论】:

  • 糟糕,我一定是自己搞糊涂了,你说的完全正确。
  • 您好,CertainPerfomance,感谢您提供的非常翔实的回答,它不仅提出了修复建议,还告诉了我为什么我正在做的事情没有像我想象的那样工作。这个项目对我自己来说更像是一个教学练习,所以对我来说,知道它是如何工作的和让它工作一样重要。我不太熟悉您为达到预期结果而提供的方法,但这只是意味着我还有更多需要学习。
【解决方案2】:

以下是否有效?

promise.then(function (realEstate) {
  return Object.keys(realEstate).reduce(
    function(all,key){
      const items = realEstate[key].map(
        function(houseItem){
          const htmlElement = document.createElement('div');
          htmlElement.className = 'house';
          htmlElement.innerHTML =
            `<img src="${houseItem.image_url}">
                <p>${houseItem.name} <span>${houseItem.price}</span></p>
                <p>${houseItem.squareFt}</p>
                `;
          return htmlElement;
        }
      );
      return all.concat(items);
    },
    []
  );
}).then(function(htmlElements){
  const container = document.getElementById('sd-collection');
  return htmlElements.forEach(
    function(htmlElement){
      container.appendChild(htmlElement);
      return htmlElement;//you may want to do something with the html elements
    }
  )
})
.catch(function (error) {
  console.log(error);
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-05-03
    • 1970-01-01
    • 1970-01-01
    • 2017-06-21
    • 1970-01-01
    • 2017-07-20
    • 2020-11-29
    • 2019-02-12
    相关资源
    最近更新 更多