Filling a Datatable with a JSON from an API - javascript

<body>
<table id="example" class="display" style="width:100%">
<thead>
<tr>
<th>Name</th>
<th>Height</th>
<th>hair_color</th>
<th>skin_color</th>
<th>gender</th>
</tr>
</thead>
</table>
</body>
This is my table HTML
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.16/css/jquery.dataTables.min.css"/>
<script type="text/javascript" src="https://cdn.datatables.net/v/dt/dt-1.10.16/datatables.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$('#example').DataTable( {
ajax: {
url: 'https://swapi.co/api/people/1/',
dataSrc: ''
},
columns: [
{ data: 'name' },
{ data: 'height' },
{ data: 'hair_Color' },
{ data: 'skin_color' },
{ data: 'gender' }
]
} );
});
</script>
This are my scripts. I know that there are some threads about this same thing but i had no luck getting it to work, i checked Datatables documentation to try different ways but no luck, its not filling the table. The API returns me this:
{
"name": "Luke Skywalker",
"height": "172",
"mass": "77",
"hair_color": "blond",
"skin_color": "fair",
"eye_color": "blue",
"birth_year": "19BBY",
"gender": "male",
"homeworld": "https://swapi.co/api/planets/1/",
"films": [
"https://swapi.co/api/films/2/",
"https://swapi.co/api/films/6/",
"https://swapi.co/api/films/3/",
"https://swapi.co/api/films/1/",
"https://swapi.co/api/films/7/"
],
"species": [
"https://swapi.co/api/species/1/"
],
"vehicles": [
"https://swapi.co/api/vehicles/14/",
"https://swapi.co/api/vehicles/30/"
],
"starships": [
"https://swapi.co/api/starships/12/",
"https://swapi.co/api/starships/22/"
],
"created": "2014-12-09T13:50:51.644000Z",
"edited": "2014-12-20T21:17:56.891000Z",
"url": "https://swapi.co/api/people/1/"
}
Here its also a Fiddle: https://jsfiddle.net/dpq7v6ba/5/

Even you want to use object as your datasource, but your data still need to live inside a property which is need to be an array, like :
{
count:30,
data:[{...},{...},{...}......]
}
Since you want to make a list table on the screen, you should use the api that will return multiple result but not the single result api, in your api url, that is https://swapi.co/api/people/ .
by default, this library will read data from an property named "data"...
But you can give the "dataSrc" argument point out where the dataTables library should go to read the data from the response json string,
the response of the api is an one level JSON object, the data is an array of the value of the "results" property.
And you hava a wrong property mapping in the "columns" argument which should be "hair_color", not "hair_Color"
so the code will become :
$(document).ready(function() {
$('#example').DataTable( {
ajax: {
url: 'https://swapi.co/api/people/',
dataSrc: 'results'
},
columns: [
{ data: 'name' },
{ data: 'height' },
{ data: 'hair_color' },
{ data: 'skin_color' },
{ data: 'gender' }
]
} );
});
and then it will work.
JSFiddle example

Related

Share data between vega-lite graphs

I have a site with two vega-lite graphs that show different aspects of the same dataset, which is generated dynamically (similar to this example). Currently they both hold their own version of this dataset.
Since the dataset tends to get quite big I would like them to share the data between them so they use less memory.
Since the data will be updated later (from the function update_vega()) I can't just put it into a variable and embed it in both diagrams.
Is it possible in vega-lite to have multiple graphs sharing the same data-object and how can I do it?
Here is my code (I have only been learning javascript 3 days ago, so I am very happy about feedback on every level):
<!DOCTYPE html>
<html>
<body>
<!-- setup of the vega graph -->
<script src="https://cdn.jsdelivr.net/npm/vega#5.10.0"></script>
<script src="https://cdn.jsdelivr.net/npm/vega-lite#4.6.0"></script>
<script src="https://cdn.jsdelivr.net/npm/vega-embed#6.3.2"></script>
<div id="vega_graph_one"></div>
<div id="vega_graph_two"></div>
<script>
var vlSpec_one = {
$schema: 'https://vega.github.io/schema/vega-lite/v4.json',
data: { name: 'table', values: [{"time":11, "age": 4},{"time":12, "age": 4},{"time":11, "age": 5}]},
width: 400,
mark: 'bar',
encoding: {
x: {field: 'time', type: 'quantitative', binned: true},
y: {aggregate: "count", type: 'quantitative'},
color: {field: 'age', type: 'quantitative'}
}
}
var vlSpec_two = {
$schema: 'https://vega.github.io/schema/vega-lite/v4.json',
data: { name: 'table', values: [{"time":11, "age": 4},{"time":12, "age": 4},{"time":11, "age": 5}]},
width: 400,
mark: 'point',
encoding: {
x: {field: 'time', type: 'quantitative'},
y: {field: 'age', type: 'quantitative'},
}
}
// two global variables so the view can be updated from an outside function
var view_one;
var view_two;
vegaEmbed('#vega_graph_one', vlSpec_one).then(
result => { view_one = result.view;},
reason => { console.error(reason);}
)
vegaEmbed('#vega_graph_two', vlSpec_two).then(
result => { view_two = result.view;},
reason => { console.error(reason);}
)
// update the vega graph from outside
// call with update_vega([{"time":11, "age": 4},{"time":12, "age": 4},{"time":9, "age": 6}])
function update_vega(event_data){
var changeSet = vega.changeset()
.insert(
event_data
);
// data dublication happense here
view_one.change("table", changeSet).run();
view_two.change("table", changeSet).run();
}
</script>
</body>
</html>
First, consider putting your data in javascript function and call it in data, should be easier to maintain for both data and chart:
function getData(){
var mydata = [{"time":11,"age": 4},{"time":12,"age": 4},{"time":11, "age":5}];
return mydata;
}
Then you can call it:
{
"data": getData(),
"mark": {"type" : "bar"}
}
There are several concepts that help achieving data sharing based on your needs.
You need just one vegaEmbed and one vlSpec that utilizes one of the following:
Layers
Put data on top of all layers and refer to it from each mark's layer
{
"data": {"values":getData()},
"layer": [
{
"mark": {"type" : "bar"}
},
{
"mark": {"type" : "point"}
}
]
}
Concat
vconcat, hconcat, and concat can be used to produce multiple charts of different mark each using same data, it doesn't perfectly suite your case because you don't have the same x and y fields in every mark. Read more on Concatenating views
{
"data": {"values":getData()},
"concat": [
{
"mark": {"type" : "line"},
"encoding": {
"x": {"field": "time"},
"y": {"field": "age"}
}
},
{
"mark": {"type" : "bar"},
"encoding": {
"x": {"field": "time"},
"y": {"field": "age"}
}
}
]
}

Javascript dataTables populating data issue (no errors returned)

I am using data tables and trying to popular a table with data.
The data I have looks like this:
<table id="mytable" class="display" width="100%"></table>
{
"users": [
{
"id": "6700",
"user": {
"firstName": "somename"
},
"Count": 0
}
]
}
So this is what I've done:
var dataSet = {
"users": [
{
"id": "6700",
"user": {
"firstName": "somename"
},
"Count": 0
}
]
};
jQuery('#mytable').DataTable( {
data: dataSet,
columns: [
{ "users": "id" }
]
});
I'm am not getting any errors but the data is not inserted either.
What I'm I doing wrong here?
In data option you need to provide variable that contains array of objects (dataSet.users). Also in columns.data option you need to define property within each object in the array (id).
Corrected code is shown below.
jQuery('#mytable').DataTable( {
"data": dataSet.users,
"columns": [
{ "data": "id", "title": "ID" }
]
});
See this example for demonstration.

Data Table Escape Periods

I have a datatable created with datatable.js.
I set up my table using an object and columns with names:
{ "title": "image", "data": "foo1", "className": "dt-center" },
{ "title": "id", "data": "foo.bar", "className": "dt-center" },
{ "title": "name", "data": "lorem", "className": "dt-center" }
I am trying to dynamically add a row to it. I am doing this with the following code:
var Json = {
"foo1" : '5',
"foo.bar" : '3',
"lorem" : 'True'
}
var rtn = oTable.fnAddData(Json );
The problem is, I am getting the error "Requested unknown parameter "foo.bar" for row n". This page indicates that periods need to be escaped with a \\.
Unfortunately, this isn't reliable.
This is a table of the number of backslashes (\) I have used in each location.
How can I escape this so that it works in both places?
I believe your original data is in the format shown below, that is the only explanation that the dotted notation (foo.bar) in columns.data worked initially.
{
"foo1": '5',
"foo": { "bar": '3'},
"lorem": 'True'
}
Dotted notation (foo.bar) in columns.data allows to read from nested objects, so foo.bar refers to bar sub-property of property named foo.
You must pass data in the same format to fnAddData, so you need to use the code below:
var Json = {
"foo1" : '5',
"foo": { "bar" : '3' },
"lorem" : 'True'
};
var rtn = oTable.fnAddData(Json);
See the example below for code and demonstration.
$(document).ready(function() {
var oTable = $('#example').dataTable({
'columns': [
{ "title": "image", "data": "foo1", "className": "dt-center" },
{ "title": "id", "data": "foo.bar", "className": "dt-center" },
{ "title": "name", "data": "lorem", "className": "dt-center" }
]
});
var Json = {
"foo1" : '5',
"foo": { "bar" : '3' },
"lorem" : 'True'
};
var rtn = oTable.fnAddData(Json );
});
<link href="//cdn.datatables.net/1.10.7/css/jquery.dataTables.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="//cdn.datatables.net/1.10.7/js/jquery.dataTables.min.js"></script>
<table id="example" class="display" cellspacing="0" width="100%">
</table>
It is most likely a problem with the plugin code itself. Try eliminating the period entirely from the JSON key value foo.bar

DataTables - Uncaught TypeError: Cannot read property 'length' of undefined

I've seen several examples of this problem but still haven't been able to find a resolution.
The error says it breaks on jquery.dataTables.js (version 1.10.4) on line 3287 shown below
// Got the data - add it to the table
for ( i=0 ; i<aData.length ; i++ ) {
_fnAddData( settings, aData[i] );
}
This is my controller. The controller is this way because the the lack of db connection right now, but will have JSON returned in the same format as $data. I have tried several things to resolve the error, but keep running into other issues. The JSON IS valid.
public function test()
{
$data = '{"persons": [{"branch": "CORP","phone_numbers": [{"desk": "5223422117"},{"mobile": "5022319224"},{"branch": "422-922-2291"}],"email": "twilliams#test.com","preferred_name": "Thomas","person_id": 368,"department": "IT","first_name": "Thomas","title": "Programming Manager","last_name": "Williams"}]}';
$data = json_encode($data);
echo $data;
}
My javascript
$(document).ready(function() {
$('#directory_table').dataTable( {
"ajax": {
"url": "test",
"type": "JSON"
},
"aoColumns": [
{ "persons": "preferred_name" },
{ "persons": "last_name" },
{ "persons": "phone_numbers.0" },
{ "persons": "phone_numbers.1" },
{ "persons": "phone_numbers.2" },
{ "persons": "email" },
{ "persons": "department" },
{ "persons": "title" }
]
} );
} );
My HTML
<table id='directory_table' class="display">
<thead>
<tr style='background: #186A9F; color: white;'>
<th>First Name </th>
<th>Last Name</th>
<th>Desk Number</th>
<th>Mobile</th>
<th>Branch</th>
<th>Email</th>
<th>Department</th>
<th>Title</th>
</tr>
<thead>
</table>
CAUSE
By default DataTables expects JSON response to have certain structure, see documentation.
Array of arrays:
{
"data": [
[ "value1", "value2" ],
...
]
}
Array of objects:
{
"data": [
{
"attr1": "value1",
"attr2": "value2"
},
...
]
}
Error occurs because name of the data property in your response holding array of objects (persons) differs from default (data).
SOLUTION
Use ajax.dataSrc option to define the property from the data source object (i.e. that returned by the Ajax request) to read.
$('#directory_table').dataTable( {
"ajax": {
"url": "test",
"dataSrc": "persons"
},
"columns": [
{ "data": "preferred_name" },
{ "data": "last_name" },
{ "data": "phone_numbers.0.desk" },
{ "data": "phone_numbers.1.mobile" },
{ "data": "phone_numbers.2.branch" },
{ "data": "email" },
{ "data": "department" },
{ "data": "title" }
]
});
Alternatively if you can change data property name in JSON response from persons to data, then adding "dataSrc": "persons" wouldn't be needed.
DEMO
See this jsFiddle for code and demonstration.
LINKS
See jQuery DataTables: Common JavaScript console errors for more information on this and other common console errors.

Kendo grid: How to remote filter above 2 values from one column

I have one column in kendo grid but if i'm filtering opposite the server API i need to filter against two values.
It means something like this:
{
"entityName": "client",
"data": {
"take": 10,
"skip": 0,
"page": 1,
"pageSize": 10,
"filter": {
"logic": "and",
// IN FILTER IS IMPORTANT TO HAVE 2 OBJECTS
"filters": [
{
"operator": "eq",
"value": "test",
"field": "client.name"
},
{
"operator": "eq",
"value": "test",
"field": "client.surname"
}
]
},
"group": []
}
}
I tried it by this way:
filterable : {
cell :
[
{
dataTextField : "client.name",
operator : "contains"
},
{
dataTextField : "client.surname",
operator : "contains"
}
]
}
But without luck.
How can i do it please?
Many thanks for any advice.
In order to do this, you'll have to intercept the dataSource data request and change the filter inside the readOptions before it get to the server. You'll have to create a custom transport.read and each time the dataSource will request some data, it will pass the readOptions parameter to that function.
myGrid.kendoGrid({
dataSource: {
serverFiltering: true,
transport: {
read: function (readOptions) {
readOptions.filter.filters = [{
operator: "eq",
value: "test",
field: "client.name"
}, {
operator: "eq",
value: "test",
field: "client.surname"
}];
//Insert you logic to retrieve the data from the server
//You may also try to call the dataSource original read function and pass the modified readOptions
//The ajax is just an example...
$.ajax({data: readOptions}).done(function(data){
readOptions.success(data);
});
}
}
}
Remember that if you overwrite the read function, you are responsible to call the readOptions success / error function to notify the dataSource about the data callback.

Categories

Resources