Unable to access JSON Key value pairs

Unable to access JSON Key value pairs

apallavapallav Posts: 18Questions: 2Answers: 0

Hi,

I get following json object with my Ajax GET call.

{
key1 :"value`",
"key2" :"value2",
"key3":[
{"a" : "value"},
{"b" : "value"},
["c" : "value"],
....

}

with following code I was able to get key3's values but unable to directly access key1,2 values.
Please advise.

<script type="text/javascript">
        $(document).ready(function () {
        $.ajax({
                        "url": "https://url address",
                        "type": "GET",
                       "contenType": 'application/json',
                        "dataType" : "json",
                        "headers": { "Authorization": "Bearer bearerstring","accept": "application/json"}
}).done( function(data) {
  $('#example').DataTable({
    "aaData":data,
        "columns": [
      { "data": "key1"}, // does not get any values
    ],
"aaData": data.key3,
        "columns": [
      { "data": "b"}, // gets key3 array of object's 3b's value
    ]  
  })
})
});
    </script>

This question has an accepted answers - jump to answer

Answers

  • kthorngrenkthorngren Posts: 20,264Questions: 26Answers: 4,764
    edited May 2023

    Its hard to tell exactly how you want the data displayed. Are you looking for something like this example?

    If not maybe you can use columns.render to render the key3 array into the cell.

    Also you are duplicating you have duplicated data and columns options. You only want to define one of each. Otherwise the second will overwrite the first. This is a Javascript object where you can only have one key, for example columns.

    If this doesn't help then please provide a more complete representation of the response JSON object and how you want it displayed.

    Kevin

  • apallavapallav Posts: 18Questions: 2Answers: 0

    Hello Kevin.

    I see your point about overwriting data columns.

    I will be looking at some thing like this:

    {
        "name": "Tiger Nixon",
        "hr": {
            "position": "System Architect",
            "salary": "$3,120",
            "start_date": "2011/04/25"
        },
        "contact": [
            {"city" :"Edinburgh",
            "Street":"5421"
            }
        ]
    }
    
    

    with code

    $("#table").DataTable({
      ajax: {
        url: "/echo/json/",
        method: 'GET',
        data: {
          json: JSON.stringify(json)
        }
    
      },
      columns: [{
          "data": "name"
        },
        {
          "data": "hr.position"
        },
        {
          "data": "hr.salary"
        },
        {
          "data": "contact.city"
        }
      ],
      });
    
    
    [Fiddle example]( https://jsfiddle.net/gaowfqxL/ "Fiddle example")
    
    I am getting exactly same "Loading" error
    
    
  • allanallan Posts: 61,635Questions: 1Answers: 10,092 Site admin

    Did you have a look at the network inspector in your browser? The respond from GET /echo/json/ is 404. It should be a POST request according to their docs.

    A couple of other things:

    1. The JSON should be an array (i.e. on entry in the array per row)
    2. Since you have a top level array, you should use ajax.dataSrc as an empty string, like in this example.
    3. You had contact in the data as an array, not an object. But in the DataTable config it was referenced as an object.

    Correcting these allows it to run: https://jsfiddle.net/Lwmrc987/ .

    Allan

  • apallavapallav Posts: 18Questions: 2Answers: 0

    Hi Allan,

    I am "GET"ing json object through Ajax call ( tried both within and outside of DataTables function) and yes, network inspector shows successful json object. However my json object starts with {} not [].

    Here is the fiddle updated with actual json object ( stringified)
    https://jsfiddle.net/hpc4bznu/

    I am at loss as to how I pass this json object to my dateable. Above code with .done function with aaData only gave me successful , non ideal solution so far.

    please help!

  • kthorngrenkthorngren Posts: 20,264Questions: 26Answers: 4,764

    Its not clear to me what data you want to display in the table. As Allan mentioned Datatables expects the rows to be in an array. I updated the example to place the variants object in the table.
    https://jsfiddle.net/my0tshp8/

    I commented out the ajax option but show what you would need to fetch the data and display the variants array. I added the data option to show how you would display the same variants array. The columns.data will be the same for either option.

    Hope this gets you started. If you need more help then please tell us what you want displayed.

    Kevin

  • apallavapallav Posts: 18Questions: 2Answers: 0
    edited May 2023

    Hi Kevin,

    Going back to my first post, how do I access key, values pairs outside of the arrays. For example, "lab_id" key and its value? Plus how do I iterate through various data arrays if I have

    data: json.variants
    
    

    Look at this attempt:

    https://jsfiddle.net/gej1ov2f/`

  • allanallan Posts: 61,635Questions: 1Answers: 10,092 Site admin

    What values from your data set do you want to show in the table?

    Allan

  • apallavapallav Posts: 18Questions: 2Answers: 0

    In multiple tables,

    following in one table, but I am baffled as to how to access this data with "columns" structure.

      "lab_id": "LAB101",
      "study_id": "NCT101",
      "is_registered": false,
      "lab_scenario_id": "SAMPLE01",
      "specimen_collection_date": "2023-04-13T00:00:00+00:00",
      "specimen_sequencing_date": "2023-04-13T00:00:00+00:00",
      "sample_type": "SOMATIC",
    

    variants and other arrays, I could do by flattening using dataSrc .

    My question is how do I access lab_id etc k,v pairs thet are outside of array /array of objects.

  • kthorngrenkthorngren Posts: 20,264Questions: 26Answers: 4,764

    Is the json data in the test case considered one record?

    Assuming it is then use row.add() which won't expect an array of rows. Initialize an empty Datatable then in your jQuery ajax() .done() or success function use row.add() to add the one row. Updated example:
    https://jsfiddle.net/6onzvusf/

    Kevin

  • kthorngrenkthorngren Posts: 20,264Questions: 26Answers: 4,764
    edited May 2023 Answer ✓

    Or place the JSON data in an array like this:
    https://jsfiddle.net/9dvp2zbn/

    This way you can have one or more records in the JSON data.

    Depending on how you want to display variants etc you might not need to flatten them. Do you want to display the variants array in one row or have one row per variant?

    Kevin

  • apallavapallav Posts: 18Questions: 2Answers: 0

    I see, what you did with the array. Cool. This is super helpful.Both of above solutions will work for me.

    Thank you very much for your time and help!

  • apallavapallav Posts: 18Questions: 2Answers: 0

    Hi, Me again.

    How do I append rows with rowsspan feature. for example as below.

                 var table = $('#example').DataTable({
                                    "ajax" : {"url" : "test.json",
                                              "dataSrc" : ""
                                            },
                                    //data : json,  
                                    columns: [
                                    { 'data': 'lab_scenario_id' },
                                    { 'data': 'specimen_collection_date' },
                                    { 'data': 'specimen_sequencing_date' },
                                    { 'data': 'study_id' },
                                    { "data" : "scenario_id"},
                                    { 'data': 'is_registered'},
                                    { 'data': "assignment_ids",
                                      "render" : function(d,t,r){
                                        if(d == null) { return "None"}
                                        else{ return d.split(",").join("<br/>");}
                                       }
                                    },
                                   {'data' : "treatment_assignment_reports[,].report[,].id",
                                     "render" : function(d,t,r){
                                        if(d == null) { return "None"}
                                        else{ return d.split(",").join(",<br/>");}
                                       }                            
                                    },
                                   {'data' : "treatment_assignment_reports[,].report[,].assignment_status"}, 
                                                               
                                   /*{'data' : "treatment_assignment_reports[,].report",
                                   "render" : function(d,t,r){ 
                                              var str ="";
                                             for (var i = 0; i < d; i++) {
                                                str +="<tr><td rowspan=\"7\">"+d+"</td></tr>"; 
                                         };return str; 
                                     }                                                      
                                    },      */ 
                                ],
                                columnDefs : [
                                                { width: 30, targets: 0 },
                                                { width: 30, targets: 1 },
                                                { width: 30, targets: 2 },
                                                { width: 5, targets: 3 },
                                                { width: 5, targets: 4 },
                                                { width: 3, targets: 5 },
                                                { width: 3, targets: 6 },
                                                {targets : 7,
                                                    "render" : function(d,t,r){
                                              var str =""; 
                                              var values = d.split(",");
                                             $.each(values,function(index,value){
                                                table.row.add("<td rowspan=\"8\">"+value+"</td>"); 
                                               })
                                              }
                                           }
                    
                                            ],
                            });
    

    and image of the output below:

    uploaded.

  • allanallan Posts: 61,635Questions: 1Answers: 10,092 Site admin

    You don't. DataTables does not support rowspan or colspan in the table body.

    You might be able to do what you are looking for with a child row.

    Allan

  • apallavapallav Posts: 18Questions: 2Answers: 0
    edited May 2023

    Oh. ok.

    Do I iterate through json array values to create child rows then?

    In this example I would like to instantiate a child table for future styling.

     function format(d) {
        // `d` is the original data object for the row
        return (
            '<table id="childtable" cellpadding="5" cellspacing="0" border="0" style="padding-left:50px;">' +
            '<tr><td>Treatment Arms</td><td>'+ treatment_assignment_reports[,].report[,].id +'</td></tr>'+
            '<td>Assignment Status:</td><td>'+ treatment_assignment_reports[,].report[,].assignment_status +'</td></tr>' +
            '<tr><td>Reason:</td><td>'+ treatment_assignment_reports[,].report[,].reason +'</td></tr>' +
            '</table>'
            );
        }
            });
    

    Looks like "," are not allowed in a function above.

    Could you give me an example iteration please? I am looking to create individual row for each id, assignment_status and reason values from result array.

  • kthorngrenkthorngren Posts: 20,264Questions: 26Answers: 4,764

    Looks like "," are not allowed in a function above.

    That's right. The format function is a standard Javascript function. I believe treatment_assignment_reports[,] is magic that Datatables uses but is not something supported by Javascript. You could use a forEach loop or any loop of your choice to iterate the treatment_assignment_reports array. Within the loop build and append your tr and td to the HTML string that will be returned.

    Kevin

  • apallavapallav Posts: 18Questions: 2Answers: 0

    Like this in “column” block?
    How do I pass this to child table across 3 column fields?
    Use row append?

    Appreciate an example.

      {targets : 7,
                                       "render" : function(d,t,r){
                                 var str ="";
                                 var values = d.split(",");
                                $.each(values,function(index,value){
                                   table.row.add("<td rowspan=\"8\">"+value+"</td>");
                                  })
                                 }
                              }
    
    
  • kthorngrenkthorngren Posts: 20,264Questions: 26Answers: 4,764
    edited May 2023

    Here is a simple example:
    https://live.datatables.net/vanaqixu/1/edit

    It loops through the contact array to build a table row to display. It is up to you how you display the data and which data is displayed. The HTML can be any valid HTML structure like a table or a list. There is nothing Datatables specific that happens in the format function. BTW, you can name the function anything you like. It doesn't have to be format.

    Like this in “column” block?

    The format function is used to build the HTML string you want to display in the child. The child rows are not Datatables rows so APIs like row.add() wont work. In fact row.add() is not intended to be used in columns.render.

    How do I pass this to child table across 3 column fields?

    The row.child(format(row.data())).show(); statement passes the full row data into the format function using row.data()). You can access any of the row data in the function. Use the browser's debugger or a console.log statement to see what is passed into the function, ie, what does d contain.

    Use row append?

    Datatables inserts a tr that contains the HTML that is returned from the format function.

    If you still need help then please update my example with a sample of that data you want help with and specifics of how you want it displayed.

    Kevin

  • apallavapallav Posts: 18Questions: 2Answers: 0

    Ok. Please check here.

    I would like to display :

    <tr><td>Report.id</td><td>report.assignment_status</td><td>report.reason</td></tr>
    
    
  • kthorngrenkthorngren Posts: 20,264Questions: 26Answers: 4,764

    Here is the updated example:
    https://live.datatables.net/vanaqixu/3/edit

    It loops through the treatment_assignment_reports array then through the reports.report array to output all the rows. Note the added CSS and div tag usage for the last column to allow wrapping the text. You can change this in anyway you wish to display the long text.

    Kevin

  • apallavapallav Posts: 18Questions: 2Answers: 0

    Got it. Thanks , You are a life saver. :wink:

  • apallavapallav Posts: 18Questions: 2Answers: 0

    Me again :(

    How do I accomplish this:

    var boolean
    
    

    is based on if the treatment_assignment_reports.assignment_ids array is populated.

     {  'data' : null,
                       'ordarable' : false,
                       'defaultContent' : "", 
                      'render' : function(d,t,r,m){
                                 if(boolean == "false"){ 
                                    $('td').addClass("details-control2");
                                    }else{
                                    $('td').addClass("details-control");
                                    }       
                              }
                            },
    
  • kthorngrenkthorngren Posts: 20,264Questions: 26Answers: 4,764
    edited May 2023

    The third parameter of columns.,render, r in your example, contains the full row of data. Use the JS length property. Something like this:

    if ( r.treatment_assignment_reports.assignment_ids.length === 0 ) {
      $('td').addClass("details-control2");
    } else {
       $('td').addClass("details-control");
    }      
    

    The path of r.treatment_assignment_reports.assignment_ids might be different depending on the structure of your object.

    BTW, if(boolean == "false"){ won't work as "false" is a string not a boolean value. You would use something like this if(boolean == false){ or better is use if( ! boolean){. Its the logical not operator.

    Kevin

  • apallavapallav Posts: 18Questions: 2Answers: 0

    This is what I liked. and it works as expected. Thanks for getting back.

                    {  'data' : null,
                       'ordarable' : false,
                       'defaultContent' : "",
                       'render' : function(d,t,r,m){
                                 if(boolean == true){ 
                                    $('tbody tr td').eq(7).addClass("details-control2");
                                    }else{
                                    $('tbody tr td').eq(7).addClass("details-control");
                                    }       
                              }
                            },
    
  • apallavapallav Posts: 18Questions: 2Answers: 0

    Hi Kevin,

    Could you please take a look here and help me get the row data added to the child dataTable?

    I attached screenshots of how they were looking before., after the child data table initialization.

  • apallavapallav Posts: 18Questions: 2Answers: 0

    screen shots failing to upload.

  • kthorngrenkthorngren Posts: 20,264Questions: 26Answers: 4,764

    Are you trying to use Datatables in the child row? If so see this blog for the best practice way to use Datatables in the child row. Since you aren't using Editor you can ignore those sections of code.

    Kevin

  • apallavapallav Posts: 18Questions: 2Answers: 0

    I am since I can not add bootstrap classes or sorting in child rows.

    the blog post is slightly confusion to me. Please see here updated fiddle and let me know how do I get the child dateable instantiated.

    https://jsfiddle.net/8Lhxbo3s/3/
    
    
  • kthorngrenkthorngren Posts: 20,264Questions: 26Answers: 4,764

    In the blog there is a link to the full source code which may help.

    I updated your example based on the blog source code:
    https://jsfiddle.net/dwc5o37t/

    In the click event handler the createChild() function is called with the row.

        else {
            // Open this row
            createChild(row);
            //row.child(createChild((row.data()))).show();
        tr.addClass('shown');
    

    In the function the row data is fetched:

    function createChild (row ) {
    
        var d = row.data();  
    ....
    

    It seems that instead of building a string you will need to build a jQuery object representing the table. I didn't adjust your code but put an example at the end of the function.

      // Build HTML structure
      table = $('<table></table>');
      thead = $('<thead><th>test</th></thead');
      tbody = $('<tbody></tbody>');
      $(tbody).append('<tr><td>data1</td></tr>');
      $(tbody).append('<tr><td>data2</td></tr>');
      
      $(table).append(thead);
      $(table).append(tbody);
    
      // Show table element
      row.child( table ).show();
     
      // Init Datatables
      $( table ).DataTable();
    

    Kevin

  • apallavapallav Posts: 18Questions: 2Answers: 0

    Works like a charm,Kevin. Thank you very much for your help!

Sign In or Register to comment.