Passing nested JSON values via API

Passing nested JSON values via API

east1999east1999 Posts: 31Questions: 11Answers: 0

Hi,

I'm trying to implement the Highcharts example on my table, basically linking a bar graph to the table, which updates with search.

I already built an example using the Type column (X: Name of type, Y: Nr. of type), but I want to go further by adding Time. So you can see a distribution of Type(s) of records for all the years indexed in the table, updating as you search or filter.

The problem is my Time variable comes from a deeply nested JSON variable.

Here's an excerpt of my working code:

initComplete": function getdata (settings, json) {
      
    var data = table.rows().data();

    var categories=[]; //creating array for storing type in array.
        for(var i=0;i<data.length;i++){
        categories.push(data[i]["type"])
    }

      var count = {}; //creating object for getting a count
          categories.forEach(function(i) {
          count[i] = (count[i]||0)+1;  
      });

      console.log(count) 

      var series_data=[]; //creating empty array for highcharts series data
      var types=[];//creating empty array for highcharts categories
      
      Object.keys(count).map(function(item, key) {
          series_data.push(count[item])
          types.push(item)
          });

      console.log(types)

      plotChart(types, series_data)

If i replace data[i]["type"] with the proper direction to my date property, using data[i]["issued.date-parts.0.0"], I get object undefined, end of story. In fact, whenever I try to access JSON properties, I'm rarely able to extract the date, though that line works perfectly in the data for columns (as simply data: "issued.date-parts.0.0").

Any clues? Is it possible to extract the values from the actually-loaded table, or am I repeating a procedure? I tried to use data[0](choosing column values), as described here, but it's probably looping back to JSON and just returning undefined.

This question has an accepted answers - jump to answer

Answers

  • kthorngrenkthorngren Posts: 20,302Questions: 26Answers: 4,769

    If I understand your data structure correctly try changing data[i]["issued.date-parts.0.0"] to data[i].issued.date-parts.0.0. Or you could use the form data[i]["issued"]["date-parts"]["0"]["0"].

    Kevin

  • east1999east1999 Posts: 31Questions: 11Answers: 0

    First one will say SyntaxError: Unexpected number '.0'. Expected ')' to end an argument list., second one will say TypeError: undefined is not an object (evaluating 'data[i]["issued"]["date-parts"]').

    Here you can read some more about the structure of my JSON, which I'm starting to think is the real problem. However, like I said, issued.date-parts.0.0 works fine to inject data into a column, which is the real mystery.

  • kthorngrenkthorngren Posts: 20,302Questions: 26Answers: 4,769
    edited February 2018

    I see this from your SO post:

        "issued": {
            "date-parts": [
                [
                    "2000"
                ]
            ]
        },
    

    date-parts is an array of arrays. Sounds like you are only interested in the first element of the inner array. Which I think you would access like this: data[i].issued.date-parts[0][0]. Note there are no quotes around the 0's.

    However, like I said, issued.date-parts.0.0 works fine to inject data into a column, which is the real mystery.

    Interesting, I just tried this and it works. @allan can explain why it works but I suspect his code handles it properly depending on whether 0 is an array or object.

    EDIT: You will need to use data[i].issued["date-parts"][0][0]. Having a "-" won't work with this syntax data[i].issued.date-parts[0][0].

    Kevin

  • east1999east1999 Posts: 31Questions: 11Answers: 0

    Doesn't work. Let me try to get a fiddle for this.

  • kthorngrenkthorngren Posts: 20,302Questions: 26Answers: 4,769
    edited February 2018 Answer ✓

    I see, the above works if you are accessing the original data through Javascript. Looks like you want to access it from var data = table.rows().data(); in initComplete. Looking at it here:
    http://live.datatables.net/gupuxado/2/edit

    Console output:

    First row {id: "http://...", type: "example-type", title: "Example title", container-title: "Example container title", page: "1-100", …}
    date-parts contains array [Array(1)]0: ["2000"]length: 1__proto__: Array(0)
    date-parts[0] contains array ["2000"]
    array element 0 (date-parts[0][0])contains data 2000
    

    You can see the structure as Datatables stores it. You will need to use data[i].issued["date-parts"][0][0].

    Also note that referencing the variable (table) you are assigning to Datatables is not available yet within the initComplete function. You should get an undefined error from this. You can use something like this:
    var data = $('#myTable').DataTable().rows().data();

    EDIT: Made a couple updates to this post.

    Kevin

  • east1999east1999 Posts: 31Questions: 11Answers: 0

    Here's a bit of an oblique answer while I analyse your code:

    https://jsfiddle.net/8qrojfoz/6/

    Here it is working. What's the difference?

    When I try to run it locally using my own json, same error line:
    [Error] TypeError: undefined is not an object (evaluating 'json[i]["issued"]["date-parts"]')

    I think this might have to do with some problems in the JSON file. This field will often appear as "year":

    "issued": { "date-parts": [ [ "2001" ] ] }

    But sometimes it appears as "year", month, day:

    "issued": { "date-parts": [ [ "2001", 10, 26 ] ] }

    I surmise this is why it gets misread sometimes.

  • east1999east1999 Posts: 31Questions: 11Answers: 0

    Ok, after a long time of debugging... two empty "issued" fields (out of 4000 entries) were causing the problem. It all works now. Please look at my other question about the chart if you can.

This discussion has been closed.