首页 > 解决方案 > 无法访问对象键

问题描述

我正在向当地公交系统发出 API 请求。我得到了我需要的 JSON 对象。但是当我试图访问该stop对象内的密钥时。它说无法读取未定义的属性。但是当我检查对象时,它就在那里阅读。

错误在addDataToHtml. 我是 JS 新手,请让我知道我在这里犯了什么错误。

const apiKey = 'XXXXXXXXXXXXXX';
const query = 'streets.json?name=henlow bay&';
const stops = 'stops.json?street='
let stopsArray;
let promises = [];
const mainDiv = document.querySelector('.main-container')

const stopSchedules = stopKey => {
  return fetch(`${host}stops/${stopKey}/schedule.json?${apiKey}`)
}

const promise = json => {
  json.stops.forEach(e => {
    promises.push(stopSchedules(e.key))
  })
  return promises;
}

const addDataToHtml = jsonData => {
  Promise.all(promise(jsonData))
    .then(response => {
      return stopsArray = response.map( e => e.json())
    })
    .then((response)=> {
      console.log(response);
       response.forEach(e =>{
       console.log(e['stop-schedule'].stop.name);
       })
    })  
}

fetch(`${host}${query}${apiKey}`)
  .then((response) => response.json())
  .then((responseData) => fetch(`${host}${stops}${responseData.streets[0].key}&${apiKey}`))
  .then((stopsRespose) => stopsRespose.json())
  .then((stopsJson) => addDataToHtml(stopsJson))

我在这里得到的 Json 对象如下。

{
  "stop-schedule": {
    "stop": {
      "key": 60433,
      "name": "Northbound Henlow at Fultz",
      "number": 60433,
      "direction": "Northbound",
      "side": "Farside",
      "street": {
        "key": 1717,
        "name": "Henlow Bay",
        "type": "Bay"
      },
      "cross-street": {
        "key": 1400,
        "name": "Fultz Boulevard",
        "type": "Boulevard"
      },
      "centre": {
        "utm": {
          "zone": "14U",
          "x": 630170,
          "y": 5519519
        },
        "geographic": {
          "latitude": "49.81398",
          "longitude": "-97.19061"
        }
      }
    },
    "route-schedules": [
      {
        "route": {
          "key": 94,
          "number": 94,
          "name": "Route 94 Whyte Ridge - Fort Garry",
          "customer-type": "regular",
          "coverage": "regular"
        },
        "scheduled-stops": [
          {
            "key": "11245829-34",
            "cancelled": "false",
            "times": {
              "arrival": {
                "scheduled": "2019-05-20T17:44:10",
                "estimated": "2019-05-20T17:43:15"
              },
              "departure": {
                "scheduled": "2019-05-20T17:44:10",
                "estimated": "2019-05-20T17:43:15"
              }
            },
            "variant": {
              "key": "94-0-H",
              "name": "to Henlow & Scurfield"
            },
            "bus": {
              "key": 211,
              "bike-rack": "false",
              "wifi": "false"
            }
          },
          {
            "key": "11245818-34",
            "cancelled": "false",
            "times": {
              "arrival": {
                "scheduled": "2019-05-20T18:27:10",
                "estimated": "2019-05-20T18:27:10"
              },
              "departure": {
                "scheduled": "2019-05-20T18:27:10",
                "estimated": "2019-05-20T18:27:10"
              }
            },
            "variant": {
              "key": "94-0-H",
              "name": "to Henlow & Scurfield"
            },
            "bus": {
              "key": 211,
              "bike-rack": "false",
              "wifi": "false"
            }
          }
        ]
      }
    ]
  },
  "query-time": "2019-05-20T17:33:44"
}

标签: javascriptapi

解决方案


与 Khauri McClain 一起,我感觉问题的一部分是您期望 JSON 值的数组。如果您只为这些数组值之一包含了 JSON,那么这不是一个真正的问题。

我的另一个担心是 .map 不是 JSON 解码完整对象。可能只是解码第一级,所以“stop”、“route-schedules”等都是字符串。

React - 如何映射嵌套对象值?

如上面的链接所述,您可能需要嵌套 .map 来获取所有内容。由于您有相当嵌套的对象,您可能希望使其递归以获取所有内容,而无需手动执行。

或者,您可以只使用 JSON.parse() 在一次调用中自动执行此操作。

编辑:
你不应该在JSON.parse里面.map做,你应该做而不是.map.

在 JavaScript 中解析 JSON?

https://www.w3schools.com/jsref/jsref_parse_json.asp

我从 W3Schools TryIt 示例中借用了这个,但是在浏览器的 DevTools/console 中运行它,然后稍微玩一下:

var obj = JSON.parse('{"firstName":"John", "lastName":"Doe", "nested":{"testing":40}}');

document.getElementById("demo").innerHTML = obj.firstName;
document.getElementById("demo").innerHTML += obj.nested.testing;

这应该输出:

约翰40

只需将您的整个 Json 对象推入JSON.parse,看看会发生什么。我不认为它会处理你得到的对象数组,但试一试。

此外,经过一些测试,您甚至可能根本不需要它response.map( e => e.json()),因为它response可能已经是一个 Json 对象。我已经尝试过已经是 Json 对象的对象,并且这两种方法都没有返回任何结果.jsonJSON.parse你可能做的太多了。

在这一点上,我建议console.log你做一个变量,或者更好的是,将它们分配给一个window变量,这样你就可以在控制台中使用它们进行手动测试:

window.r = response;

当我不知道我正在处理什么结构时,我经常这样做。它让我可以玩一些应该在代码中工作的东西。诚然,并非所有 ReactJS、JQuery 或其他库都可以在 DevTools 控制台中运行,但它仍然可以很好地衡量什么是什么,什么不是。


推荐阅读