2

I know this has been asked a lot, but I just can't help myself, because the my JSON has some weird format in my opinion. Im calling the bing api you can see below and it reports a JSON like this:

{
  "authenticationResultCode": "ValidCredentials",
  "brandLogoUri": "http:dev.virtualearth.netBrandinglogo_powered_by.png",
  "copyright": "Copyright © 2020 Microsoft and its suppliers. All rights reserved. This API cannot be accessed and the content and any results may not be used, reproduced or transmitted in any manner without express written permission from Microsoft Corporation.",
  "resourceSets": [
    {
      "estimatedTotal": 44,
      "resources": [
        {
          "__type": "TrafficIncident:http:schemas.microsoft.comsearchlocalwsrestv1",
          "point": {
            "type": "Point",
            "coordinates": [
              48.12575,
              11.50249
            ]
          },
          "description": "Bei München-Laim - Stockender Verkehr;; vorsichtig an das Stauende heranfahren.",
          "end": "Date(1581665178000)",
          "incidentId": 1717453254024927000,
          "lastModified": "Date(1581643942010)",
          "roadClosed": false,
          "severity": 2,
          "source": 9,
          "start": "Date(1581061714000)",
          "toPoint": {
            "type": "Point",
            "coordinates": [
              48.12562,
              11.5046
            ]
          },
          "type": 2,
          "verified": true
        },
        {
          "__type": "TrafficIncident:http:schemas.microsoft.comsearchlocalwsrestv1",
          "point": {
            "type": "Point",
            "coordinates": [
              48.10819,
              11.61907
            ]
          },
          "description": "Bei Woferlstraße - Bauarbeiten auf Abschnitt.",
          "end": "Date(1581974827000)",
          "incidentId": 4267251995514645000,
          "lastModified": "Date(1581637098936)",
          "roadClosed": false,
          "severity": 2,
          "source": 9,
          "start": "Date(1581629269000)",
          "toPoint": {
            "type": "Point",
            "coordinates": [
              48.10819,
              11.61907
            ]
          },
          "type": 9,
          "verified": true
        },
        {
          "__type": "TrafficIncident:http:schemas.microsoft.comsearchlocalwsrestv1",
          "point": {
            "type": "Point",
            "coordinates": [
              48.14469,
              11.55741
            ]
          },
          "description": "Zwischen Karlstraße und Hirtenstraße - Bauarbeiten auf Abschnitt.",
          "end": "Date(1585778340000)",
          "incidentId": 3021451548046648000,
          "lastModified": "Date(1581637098936)",
          "roadClosed": false,
          "severity": 2,
          "source": 9,
          "start": "Date(1581629270000)",
          "toPoint": {
            "type": "Point",
            "coordinates": [
              48.14314,
              11.55658
            ]
          },
          "type": 9,
          "verified": true
        },
        {
          "__type": "TrafficIncident:http:schemas.microsoft.comsearchlocalwsrestv1",
          "point": {
            "type": "Point",
            "coordinates": [
              48.14314,
              11.58826
            ]
          },
          "description": "Bei Franz-Josef-Strauß-Ring - Baustelle.",
          "end": "Date(1609369140000)",
          "incidentId": 337182766905069500,
          "lastModified": "Date(1581637098936)",
          "roadClosed": false,
          "severity": 2,
          "source": 9,
          "start": "Date(1581629314000)",
          "toPoint": {
            "type": "Point",
            "coordinates": [
              48.14423,
              11.58316
            ]
          },
          "type": 9,
          "verified": true
        },
        {
          "__type": "TrafficIncident:http:schemas.microsoft.comsearchlocalwsrestv1",
          "point": {
            "type": "Point",
            "coordinates": [
              48.141,
              11.5613
            ]
          },
          "description": "Bei Karlsplatz - Bauarbeiten auf Abschnitt. Fahrbahn von auf einen Fahrstreifen verengt.",
          "end": "Date(1581974827000)",
          "incidentId": 1310817648090719700,
          "lastModified": "Date(1581637098936)",
          "roadClosed": false,
          "severity": 2,
          "source": 9,
          "start": "Date(1581629270000)",
          "toPoint": {
            "type": "Point",
            "coordinates": [
              48.14186,
              11.56163
            ]
          },
          "type": 9,
          "verified": true
        }
      ]
    }
  ]
}

I just can't help myself to get only the description part into a simple html table. the following is what i tried by now.

<!DOCTYPE html>
<html>
<head>
</head>
<body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"> </script>
<script>
    $.getJSON("http://dev.virtualearth.net/REST/v1/Traffic/Incidents/48.052165,11.722993,48.222626,11.391344?key=BINGKEY").then(function(data)
{console.log(data);

   var tr = data
    for (var i = 0; i < data.resourceSets.estimatedTotal; i++) {
    var tr = $('<tr/>');

    // Indexing into data.report for each td element
    $(tr).append("<td>" + data.resourceSets.resources[i].description + "</td>");
    $('.table1').append(tr);
    }

});
</script>

<table class="table1">
    <tr>
        <th>description</th>
    </tr>
</table>
</body>
</html>

maybe someone can help me with my problem. Thanks

Julius Limson
  • 526
  • 9
  • 29
Simon
  • 23
  • 3

3 Answers3

2

resourceSets is collection in json and you are trying to access it as normal property.

for(var s = 0; s < data.resourceSets.length; s++) {

    for (var i = 0; i < data.resourceSets[s].resources.length; i++) { 
        var tr = $('<tr/>');

        // Indexing into data.report for each td element
        $(tr).append("<td>" + data.resourceSets[s].resources[i].description + "</td>");
        $('.table1').append(tr);
    }
}

Side but related note: estimatedTotal is 44, but in the json that is posted, has only 5 resources. Are you sure you want to iterate 44 times? if yes, you need to watch array index out of range exception.

sam
  • 1,937
  • 1
  • 8
  • 14
  • Yes, i would like to display all items, it even can be more. but i only need the description information, the rest is not relevant – Simon Feb 14 '20 at 04:48
  • In that case your for loop should not be using estimatedTotal as upper bound. I will update the answer – sam Feb 14 '20 at 04:50
1

I would declare an iterable list of fields and then dynamically loop-over the resources.

[ 'description', 'severity', 'point.coordinates[0]', 'point.coordinates[1]' ]

Note: You can append multiple items by mapping as seen below.

Update: You can resolve nested fields by implementing a recursive function as seen below.

Instead of this:

return $('<td>').text(resource[field]);

You can use this:

return $('<td>').text(resolveField(resource, field));

Warning: It's not fool-proof, because it fails at multiple nested arrays e.g. foo[0][0].

Demo

let fields = [ 'description', 'severity', 'point.coordinates[0]', 'point.coordinates[1]' ];
let data = getData();

$('.table-1 tbody').append(data.resourceSets.flatMap(resourceSet => {
  return resourceSet.resources.map(resource => {
    return $('<tr>').append(fields.map(field => {
      return $('<td>').text(resolveField(resource, field));
    }));
  });
}));

// Adapted from: https://stackoverflow.com/a/19156197/1762224
function resolveField(obj, prop) {
  return prop.match(/[^\]\[.]+/g)
    .map(token => {
      return Number.isInteger(token)
        ? parseInt(token, 10)
        : token.replace(/^['"](.+(?=['"]$))['"]$/, '$1');
    })
    .reduce((ref, curr) => {
      if (ref != null) {
        if (Array.isArray(ref)) {
          return ref[curr];
        } else if (typeof ref === 'object') {
          if (ref.hasOwnProperty(curr)) {
            return ref[curr];
          }
        }
      }
      return null;
    }, obj);
}

function getData() {
  return {
    "authenticationResultCode": "ValidCredentials",
    "brandLogoUri": "http:dev.virtualearth.netBrandinglogo_powered_by.png",
    "copyright": "Copyright © 2020 Microsoft and its suppliers. All rights reserved. This API cannot be accessed and the content and any results may not be used, reproduced or transmitted in any manner without express written permission from Microsoft Corporation.",
    "resourceSets": [{
      "estimatedTotal": 44,
      "resources": [{
          "__type": "TrafficIncident:http:schemas.microsoft.comsearchlocalwsrestv1",
          "point": {
            "type": "Point",
            "coordinates": [
              48.12575,
              11.50249
            ]
          },
          "description": "Bei München-Laim - Stockender Verkehr;; vorsichtig an das Stauende heranfahren.",
          "end": "Date(1581665178000)",
          "incidentId": 1717453254024927000,
          "lastModified": "Date(1581643942010)",
          "roadClosed": false,
          "severity": 2,
          "source": 9,
          "start": "Date(1581061714000)",
          "toPoint": {
            "type": "Point",
            "coordinates": [
              48.12562,
              11.5046
            ]
          },
          "type": 2,
          "verified": true
        },
        {
          "__type": "TrafficIncident:http:schemas.microsoft.comsearchlocalwsrestv1",
          "point": {
            "type": "Point",
            "coordinates": [
              48.10819,
              11.61907
            ]
          },
          "description": "Bei Woferlstraße - Bauarbeiten auf Abschnitt.",
          "end": "Date(1581974827000)",
          "incidentId": 4267251995514645000,
          "lastModified": "Date(1581637098936)",
          "roadClosed": false,
          "severity": 2,
          "source": 9,
          "start": "Date(1581629269000)",
          "toPoint": {
            "type": "Point",
            "coordinates": [
              48.10819,
              11.61907
            ]
          },
          "type": 9,
          "verified": true
        },
        {
          "__type": "TrafficIncident:http:schemas.microsoft.comsearchlocalwsrestv1",
          "point": {
            "type": "Point",
            "coordinates": [
              48.14469,
              11.55741
            ]
          },
          "description": "Zwischen Karlstraße und Hirtenstraße - Bauarbeiten auf Abschnitt.",
          "end": "Date(1585778340000)",
          "incidentId": 3021451548046648000,
          "lastModified": "Date(1581637098936)",
          "roadClosed": false,
          "severity": 2,
          "source": 9,
          "start": "Date(1581629270000)",
          "toPoint": {
            "type": "Point",
            "coordinates": [
              48.14314,
              11.55658
            ]
          },
          "type": 9,
          "verified": true
        },
        {
          "__type": "TrafficIncident:http:schemas.microsoft.comsearchlocalwsrestv1",
          "point": {
            "type": "Point",
            "coordinates": [
              48.14314,
              11.58826
            ]
          },
          "description": "Bei Franz-Josef-Strauß-Ring - Baustelle.",
          "end": "Date(1609369140000)",
          "incidentId": 337182766905069500,
          "lastModified": "Date(1581637098936)",
          "roadClosed": false,
          "severity": 2,
          "source": 9,
          "start": "Date(1581629314000)",
          "toPoint": {
            "type": "Point",
            "coordinates": [
              48.14423,
              11.58316
            ]
          },
          "type": 9,
          "verified": true
        },
        {
          "__type": "TrafficIncident:http:schemas.microsoft.comsearchlocalwsrestv1",
          "point": {
            "type": "Point",
            "coordinates": [
              48.141,
              11.5613
            ]
          },
          "description": "Bei Karlsplatz - Bauarbeiten auf Abschnitt. Fahrbahn von auf einen Fahrstreifen verengt.",
          "end": "Date(1581974827000)",
          "incidentId": 1310817648090719700,
          "lastModified": "Date(1581637098936)",
          "roadClosed": false,
          "severity": 2,
          "source": 9,
          "start": "Date(1581629270000)",
          "toPoint": {
            "type": "Point",
            "coordinates": [
              48.14186,
              11.56163
            ]
          },
          "type": 9,
          "verified": true
        }
      ]
    }]
  };
}
table { border-collapse: collapse; }
table, th, td { border: thin solid #AA5555; }
th, td { padding: 0.25em; }
thead tr { background: #EE8888; }
tbody tr:nth-child(even) { background: #EECCCC; }
tbody tr:nth-child(odd)  { background: #FFEEEE; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="table-1">
  <thead>
  <tr>
    <th>Description</th>
    <th>Severity</th>
    <th>Lat</th>
    <th>Lon</th>
  </tr>
  </thead>
  <tbody>
  </tbody>
</table>

Here is a test suite for the resolveField function:

let foo1 = { bar : 10 };
let foo2 = { bar : { baz : [ 1, 2 ] } };
let foo3 = { bar : [ { baz : 1 }, { baz : 2 } ] };

console.log(resolveField(foo1, 'bar')        === 10);
console.log(resolveField(foo2, 'bar.baz[0]') ===  1);
console.log(resolveField(foo3, 'bar[1].baz') ===  2);
Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132
0

It is very hard to parse json in javascript and display that data in html.Handlebars is the option to your solution.The dynamic data produced from the API can be easily embedded using handlebars.Refer the site below for more information.Hope this helps.

Introduction to Handlebars.js

sachin
  • 777
  • 5
  • 10
  • Link only answers are discouraged, you should provide an example of how to use Handlebars to solve the problem. Further more "It is very hard to parse json .... and display it in a table" is quite bold. Sam am Mr Polywhirl answers suggest it is actually quite easy (because it is) – Jon P Feb 14 '20 at 04:55
  • Will follow it from now onwards.Thanks. – sachin Feb 14 '20 at 06:01