获取JSON数组(API),其中对象是在与对象的对象使用Javascript

问题描述:

我使用下面的代码来建立一个基于API的表,并且当数组中的对象存在时很好(例如lineStatuses [0] .statusSeverityDescription) ,但是当有一个对象,在一个对象中,在一个数组中,它不起作用,我得到返回结果[object Object]。获取JSON数组(API),其中对象是在与对象的对象使用Javascript

下面是从URL的JSON数据的样本(我期待未定义的第一条记录将被返回):

[ 

    { 

    "$type": "Tfl.Api.Presentation.Entities.Line, Tfl.Api.Presentation.Entities", 

    "id": "bakerloo", 

    "name": "Bakerloo", 

    "modeName": "tube", 

    "disruptions": [], 

    "created": "2016-06-03T12:36:54.19Z", 

    "modified": "2016-06-03T12:36:54.19Z", 

    "lineStatuses": [ 

     { 

     "$type": "Tfl.Api.Presentation.Entities.LineStatus, Tfl.Api.Presentation.Entities", 

     "id": 0, 

     "statusSeverity": 10, 

     "statusSeverityDescription": "Good Service", 

     "created": "0001-01-01T00:00:00", 

     "validityPeriods": [] 

     } 

    ], 

    "routeSections": [], 

    "serviceTypes": [ 

     { 

     "$type": "Tfl.Api.Presentation.Entities.LineServiceTypeInfo, Tfl.Api.Presentation.Entities", 

     "name": "Regular", 

     "uri": "/Line/Route?ids=Bakerloo&serviceTypes=Regular" 

     } 

    ] 

    }, 

    { 

    "$type": "Tfl.Api.Presentation.Entities.Line, Tfl.Api.Presentation.Entities", 

    "id": "central", 

    "name": "Central", 

    "modeName": "tube", 

    "disruptions": [], 

    "created": "2016-06-03T12:36:54.037Z", 

    "modified": "2016-06-03T12:36:54.037Z", 

    "lineStatuses": [ 

     { 

     "$type": "Tfl.Api.Presentation.Entities.LineStatus, Tfl.Api.Presentation.Entities", 

     "id": 0, 

     "lineId": "central", 

     "statusSeverity": 5, 

     "statusSeverityDescription": "Part Closure", 

     "reason": "CENTRAL LINE: Saturday 11 and Sunday 12 June, no service between White City and Ealing Broadway/West Ruislip. This is to enable track replacement work at East Acton and Ruislip Gardens. Replacement buses operate.", 

     "created": "0001-01-01T00:00:00", 

     "validityPeriods": [ 

      { 

      "$type": "Tfl.Api.Presentation.Entities.ValidityPeriod, Tfl.Api.Presentation.Entities", 

      "fromDate": "2016-06-11T03:30:00Z", 

      "toDate": "2016-06-13T01:29:00Z", 

      "isNow": false 

      } 

     ], 

     "disruption": { 

      "$type": "Tfl.Api.Presentation.Entities.Disruption, Tfl.Api.Presentation.Entities", 

      "category": "PlannedWork", 

      "categoryDescription": "PlannedWork", 

      "description": "CENTRAL LINE: Saturday 11 and Sunday 12 June, no service between White City and Ealing Broadway/West Ruislip. This is to enable track replacement work at East Acton and Ruislip Gardens. Replacement buses operate.", 

      "additionalInfo": "Replacement buses operate as follows:Service A: White City - East Acton - North Acton - West Acton - Ealing Common (for District and Piccadilly Lines) - Ealing BroadwayService B: White City - North Acton - Northolt - South Ruislip - Ruislip Gardens - West RuislipService C: White City - North Acton - Park Royal (Piccadilly Line) - Hanger Lane - Perivale - Greenford - Northolt", 

      "created": "2016-05-12T11:04:00Z", 

      "affectedRoutes": [], 

      "affectedStops": [], 

      "isBlocking": true, 

      "closureText": "partClosure" 

     } 

     } 

    ], 

    "routeSections": [], 

    "serviceTypes": [ 

     { 

     "$type": "Tfl.Api.Presentation.Entities.LineServiceTypeInfo, Tfl.Api.Presentation.Entities", 

     "name": "Regular", 

     "uri": "/Line/Route?ids=Central&serviceTypes=Regular" 

     } 

    ] 

    } 

] 

我也试图用setInterval来刷新管破裂DIV与来自API的更新数据不一致。以下是代码(URL返回上面的一些JSON数据)。任何想法我做错了什么?

var xmlhttp = new XMLHttpRequest(); 
var url = "https://api.tfl.gov.uk/line/mode/tube/status"; 

xmlhttp.onreadystatechange=function() { 
    if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { 
     myFunctionDisruption(xmlhttp.responseText); 
    } 
}; 

xmlhttp.open("GET", url, true); 
xmlhttp.send(); 

setInterval(myFunctionDisruption, 600000); 

function myFunctionDisruption(response) { 
    var arr = JSON.parse(response); 
    var i; 
    var out = "<table>"; 

    for(i = 0; i < arr.length; i++) { 
     out += "<tr><td>" + 
     arr[i].lineStatuses[0].disruption.description + <!-- DOES NOT WORK --> 
     "</td></tr>"; 
    } 
    out += "</table>"; 
    document.getElementById("tube-disruption").innerHTML = out; 
} 

下面的代码会为您生成一个表格。通用tableMaker函数接受第一个参数中提供的一个对象数组或一个由多个对象组成的数组。所有对象都应具有相同的键(属性),因为这些键用于创建表头(如果第二个参数设置为true)并且这些值用于创建每一行。它将返回一个HTML表格文本。您可以在here处看到使用较小尺寸数据的tableMaker函数。您也可以使用您可能生成的一些示例和简单数据来练习它。

在你的情况下,你有多个嵌套对象,我猜,需要在主表的相应单元格内转换成单独的表格。为此,我有另一个功能tabelizer,它通过使用tableMaker函数递归地处理这项工作。 tabelizer的结果是主表的完整HTML文本。

让我们来看看

var tableMaker = (o,h) => {var keys = o.length && Object.keys(o[0]), 
 
          rowMaker = (a,t) => a.reduce((p,c,i,a) => p + (i === a.length-1 ? "<" + t + ">" + c + "</" + t + "></tr>" 
 
                          : "<" + t + ">" + c + "</" + t + ">"),"<tr>"), 
 
          rows = o.reduce((r,c) => r + rowMaker(keys.reduce((v,k) => v.concat(c[k]),[]),"td"),h ? rowMaker(keys,"th") : []); 
 
          return rows.length ? "<table>" + rows + "</table>" : ""; 
 
          }, 
 
data = [ 
 
    { 
 
    "$type": "Tfl.Api.Presentation.Entities.Line, Tfl.Api.Presentation.Entities", 
 
    "id": "bakerloo", 
 
    "name": "Bakerloo", 
 
    "modeName": "tube", 
 
    "disruptions": [], 
 
    "created": "2016-06-03T12:36:54.19Z", 
 
    "modified": "2016-06-03T12:36:54.19Z", 
 
    "lineStatuses": [ 
 
     { 
 
     "$type": "Tfl.Api.Presentation.Entities.LineStatus, Tfl.Api.Presentation.Entities", 
 
     "id": 0, 
 
     "statusSeverity": 10, 
 
     "statusSeverityDescription": "Good Service", 
 
     "created": "0001-01-01T00:00:00", 
 
     "validityPeriods": [] 
 
     } 
 
    ], 
 
    "routeSections": [], 
 
    "serviceTypes": [ 
 
     { 
 
     "$type": "Tfl.Api.Presentation.Entities.LineServiceTypeInfo, Tfl.Api.Presentation.Entities", 
 
     "name": "Regular", 
 
     "uri": "/Line/Route?ids=Bakerloo&serviceTypes=Regular" 
 
     } 
 
    ] 
 
    }, 
 
    { 
 
    "$type": "Tfl.Api.Presentation.Entities.Line, Tfl.Api.Presentation.Entities", 
 
    "id": "central", 
 
    "name": "Central", 
 
    "modeName": "tube", 
 
    "disruptions": [], 
 
    "created": "2016-06-03T12:36:54.037Z", 
 
    "modified": "2016-06-03T12:36:54.037Z", 
 
    "lineStatuses": [ 
 
     { 
 
     "$type": "Tfl.Api.Presentation.Entities.LineStatus, Tfl.Api.Presentation.Entities", 
 
     "id": 0, 
 
     "lineId": "central", 
 
     "statusSeverity": 5, 
 
     "statusSeverityDescription": "Part Closure", 
 
     "reason": "CENTRAL LINE: Saturday 11 and Sunday 12 June, no service between White City and Ealing Broadway/West Ruislip. This is to enable track replacement work at East Acton and Ruislip Gardens. Replacement buses operate.", 
 
     "created": "0001-01-01T00:00:00", 
 
     "validityPeriods": [ 
 
      { 
 
      "$type": "Tfl.Api.Presentation.Entities.ValidityPeriod, Tfl.Api.Presentation.Entities", 
 
      "fromDate": "2016-06-11T03:30:00Z", 
 
      "toDate": "2016-06-13T01:29:00Z", 
 
      "isNow": false 
 
      } 
 
     ], 
 
     "disruption": { 
 
      "$type": "Tfl.Api.Presentation.Entities.Disruption, Tfl.Api.Presentation.Entities", 
 
      "category": "PlannedWork", 
 
      "categoryDescription": "PlannedWork", 
 
      "description": "CENTRAL LINE: Saturday 11 and Sunday 12 June, no service between White City and Ealing Broadway/West Ruislip. This is to enable track replacement work at East Acton and Ruislip Gardens. Replacement buses operate.", 
 
      "additionalInfo": "Replacement buses operate as follows:Service A: White City - East Acton - North Acton - West Acton - Ealing Common (for District and Piccadilly Lines) - Ealing BroadwayService B: White City - North Acton - Northolt - South Ruislip - Ruislip Gardens - West RuislipService C: White City - North Acton - Park Royal (Piccadilly Line) - Hanger Lane - Perivale - Greenford - Northolt", 
 
      "created": "2016-05-12T11:04:00Z", 
 
      "affectedRoutes": [], 
 
      "affectedStops": [], 
 
      "isBlocking": true, 
 
      "closureText": "partClosure" 
 
     } 
 
     } 
 
    ], 
 
    "routeSections": [], 
 
    "serviceTypes": [ 
 
     { 
 
     "$type": "Tfl.Api.Presentation.Entities.LineServiceTypeInfo, Tfl.Api.Presentation.Entities", 
 
     "name": "Regular", 
 
     "uri": "/Line/Route?ids=Central&serviceTypes=Regular" 
 
     } 
 
    ] 
 
    } 
 
], 
 
tabelizer = (a) => a.length ? tableMaker(a.map(e => Object.keys(e).reduce((p,k) => (p[k] = Array.isArray(e[k]) ? tabelizer(e[k]) : e[k],p),{})),true) 
 
          : "", 
 
tableHTML = tabelizer(data); 
 
          
 
document.write(tableHTML);

我用箭头功能,但他们可能不会在Safari或IE浏览器。您可能需要将它们转换为常规函数表示法。

您也可以尝试在repl.it的代码,您可以在其中看到通过console.log显示的HTML文本。