简体   繁体   English

JSON 属性无法访问 - “无法读取未定义的属性”

[英]JSON attribute unreachable - "Cannot read property of undefined"

I am attempting to use the Wikipedia API to retrieve article titles and snippets of the article's text.我正在尝试使用 Wikipedia API 来检索文章标题和文章文本的片段。 But when I try to access those properties, I am getting the error "Cannot read property of undefined."但是当我尝试访问这些属性时,出现错误“无法读取未定义的属性”。

Here is my JSON response:这是我的 JSON 响应:

{
    "batchcomplete": "",
    "continue": {
        "gsroffset": 10,
        "continue": "gsroffset||"
    },
    "query": {
        "pages": {
            "13834": {
                "pageid": 13834,
                "ns": 0,
                "title": "\"Hello, World!\" program",
                "index": 6,
                "extract": "<p>A <b>\"Hello, World!\" program</b> is a computer program that outputs or displays \"Hello, World!\" to a user. Being a very simple program in most programming languages, it is often used to illustrate the</p>..."
            },
            "6710844": {
                "pageid": 6710844,
                "ns": 0,
                "title": "Hello",
                "index": 1,
                "extract": "<p><i><b>Hello</b></i> is a salutation or greeting in the English language. It is first attested in writing from 1826.</p>..."
            },
            "1122016": {
                "pageid": 1122016,
                "ns": 0,
                "title": "Hello! (magazine)",
                "index": 7,
                "extract": "<p><i><b>Hello</b></i> (stylised as <i><b>HELLO!</b></i>) is a weekly magazine specialising in celebrity news and human-interest stories, published in the United Kingdom since 1988. It is the United Kingdom</p>..."
            }
        }
    }
}

I have tried a couple different ways of writing the code.我尝试了几种不同的编写代码的方法。 For example, this works (logs the pages as an object in the console):例如,这有效(将页面记录为控制台中的对象):

console.log(response.query.pages);

But this returns the error I wrote above ("Cannot read property of undefined"):但这会返回我上面写的错误(“无法读取未定义的属性”):

console.log(response.query.pages[0].title);

Any suggestions on how to access the attributes "title" and "extract" would be appreciated.关于如何访问属性“title”和“extract”的任何建议将不胜感激。 Thanks.谢谢。

That's because pages is not an array;那是因为 pages 不是数组; it's an object where the keys are the ids.它是一个对象,其中键是 id。 So you need to do:所以你需要这样做:

console.log(response.query.pages[1122016].title);

This will work.这将起作用。 If you want the "first" page, for instance, then例如,如果您想要“第一”页,那么

let pages = response.query.pages;
console.log(pages[Object.keys(pages)[0]].title);

Note that I'm not sure if the order of the keys in JS objects is guaranteed.请注意,我不确定 JS 对象中键的顺序是否有保证。

If you want to iterate over the pages, do如果要遍历页面,请执行

let pages = response.query.pages;
Object.keys(pages).forEach(id => {
    let page = pages[id];
    console.log(page.title, page.foo);
});

Special Case: Working with Asynchronous Calls特殊情况:使用异步调用

Howdy fellow devs,各位开发者好,

If you're checking out this thread because you're working with a framework like React, or some other framework that has you using a development server (eg using npm start or something similar), your dev server may be crashing when you try to do something like console.log(response.foo.bar) before it refreshes on data reload.如果您正在查看此线程是因为您正在使用 React 这样的框架,或者其他一些让您使用开发服务器的框架(例如使用npm start或类似的东西),那么当您尝试使用时,您的开发服务器可能会崩溃它刷新数据重新加载之前执行类似console.log(response.foo.bar)

Specifically, my dev server was crashing with the Cannot read property 'bar' of undefined type message, and I was like, "what the heck is going on here!?".具体来说,我的开发服务器因Cannot read property 'bar' of undefined类型消息的Cannot read property 'bar' of undefined而崩溃,我想,“这到底是怎么回事!?”。 Solution: put that baby in a try/catch block:解决方案:把这个婴儿放在一个 try/catch 块中:

try { 
    console.log(rate['bar'].rate)
  } catch (error) {
    console.log(error)
  }

Why?为什么? If your App has a default state (even an empty array, for example), then it tries to console.log the response before the data has been received from the remote source, it will successfully log your empty state, but if you try to reference parts of the object you're expecting to receive from the remote source in your console.log or whatever else, the dev server will be trying to reference something not there on initial load and crash before it has a chance to reference it when it's actually received from the remote source via API or whatever.如果您的应用程序具有默认状态(例如,甚至是一个空数组),那么它会尝试在从远程源接收到数据之前对响应进行console.log ,它将成功记录您的空状态,但是如果您尝试在console.log或其他任何地方引用您希望从远程源接收的对象的一部分,开发服务器将尝试引用初始加载和崩溃时不存在的内容,然后才有机会引用它实际上是通过 API 或其他方式从远程源接收的。

Hope this helps someone!希望这可以帮助某人!

I'm not sure which language you're using to parse the JSON (looks like Javascript from console.log?) but the issue is that query.pages is a dictionary, not an array, so it can't be iterated by index, only by key.我不确定您使用哪种语言来解析 JSON(看起来像 console.log 中的 Javascript?)但问题是 query.pages 是字典,而不是数组,因此不能通过索引进行迭代,只能通过键。

So you want something like (pseudocode):所以你想要这样的(伪代码):

for (key in response.query.keys)
{
    console.log(response.query[key].title);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM