Populating DataTable column with JSON file but DataTable is empty - javascript

$.ajax({
'url': 'http://localhost:8080/Retail-war/webresources/products/allProducts',
'method': 'GET',
'contentType': 'application/json',
'headers': {"Authorization": 'Bearer ' + sessionStorage.getItem('accessToken')},
}).done( function(data) {
$('#existing-product').DataTable( {
"columnDefs": [
{ "targets": -1, "data": null, "defaultContent": "<button>View More Details!</button>"}
],
"aaData": data,
"columns": [
{ "data": "products.productId"},
{ "data": "products.originalPrice"},
{ "data": "products.currentPrice"},
]
})
This is my format of my JSON file and I would like to populate the DataTable with the 3 columns in products but nothing is showing up in the DataTable and no error is thrown too. How can I populate each columns with the columns in the JSON file under the products object?
{
"products": [
{
"productId": 1,
"originalPrice": 60,
"currentPrice": 50
},
{
"productId": 2,
"originalPrice": 80,
"currentPrice": 70
}
]
}

Instead of accessing your data like this...
// does not work
"data": data,
"columns": [
{ "data": "products.productId"},
{ "data": "products.originalPrice"},
{ "data": "products.currentPrice"}
]
Change the initializer to this:
// works
"data": data.products,
"columns": [
{ "data": "productId"},
{ "data": "originalPrice"},
{ "data": "currentPrice"}
]
DataTable needs the iterable object you will be using to be outside of the columns definitions (where the iteration happens).
These changes work for me (in my stripped-down version of your example).
UPDATE:
As requested, here are some more details to explain the situation:
If you try to use "data": data,, then you are providing a JSON object which has this structure:
{"products": [an array of objects]}
This is used by the columns definitions to iterate over your JSON. But there is nothing to iterate over - there is only the one item - the array.
However, if you first drill down one level in your structure by using "data": data.products, you are passing the following JSON to your the columns definitions:
[{row 1 data}, {row 2 data}, ... {row n data}]
This can be iterated by DataTables, to populate each row in its table.
You can still drill down into each object being iterated, if there are nested objects. In your case there aren't any nested objects - but imagine if your data looked like this (a totally artifical example, by the way):
{
"products": [{
"productId": 1,
"originalPrice": {
"currency": "USD",
"amount": 60
},
"currentPrice": 50
}, {
"productId": 2,
"originalPrice": {
"currency": "USD",
"amount": 80
},
"currentPrice": 70
}]
}
In this case, we can access the data like this:
"data": data2.products,
"columns": [
{ "data" : "productId" },
{ "data" : "originalPrice.amount" },
{ "data" : "currentPrice" }
]
Here we see the use of the dot notation to drill down into the originalPrice object, to grab the number we want to display: originalPrice.amount.

By default DataTables expects the array to be called data. You can change it using the dataSrc property, but only if you are using the built-in DataTables Ajax option, which to be honest is recommended anyway. Define your DataTable like this:
$('#existing-product').DataTable( {
ajax: {
url: "http://localhost:8080/Retail-war/webresources/products/allProducts",
dataSrc: "products",
headers: {"Authorization": 'Bearer ' + sessionStorage.getItem('accessToken')},
}
});
Alternatively rename your array on the server before you echo it back to "data"

Related

How to get a specific or multiple values (or keys) from nested JSON

I have a (nested) data structure containing objects and arrays. How can I extract the information, i.e. access a specific or multiple values (or keys)?
{
"data": [{
"name": "name1",
"value": "value1",
"list": [{
"sname": "sname1",
"svalue": "svalue1"
}, {
"sname": "sname2",
"svalue": "svalue2"
}]
}]
}
jQuery
var pk = $("#pk").val();
console.log(pk);
url = "/register/search?id=" + pk;
console.log(url);
$('#largeTable').DataTable({
"ajax": url,
"bDestroy": true,
"columns": [{
"data": "name"
},
{
"data": "value"
},
{
"data": "list.1.sname"
},
{
"data": "list.1.svalue"
},
{
"data": null,
"defaultContent": editview
}
]
});
Here it is possible to display either first or second list values by using list.1 or list.0
But I want two values at a time.
Also, how could I access the svalue of the second item in list?
I tried with data.list[1] but:
TypeError: data.list is undefined
Since data is an array, you should first get the item - and since you only have one item - you'd use data[0], and then get access to the list property like data[0].list[1] - this will give you the second item in the list - but since you are interested in a specific property (svalue) of this item, you will then access it like this: data[0].list[1].svalue.
A better approach would be to loop through the items in the data array - and then for each item, loop through the items in the list array. See #Rajesh's comment.
I hope that helps;
Specifically you can access it like this object.data[0].list[1].svalue. The reason data.list is undefined is because data corresponds to an array data: [{ }] this is why we use data[0], but data itself is a key in an object so before you can get to data you need to access it. If the objects name where data resides were object (like I did below) then it'd be accessed like this object.data[0]
const object = {
"data": [{
"name": "name1",
"value": "value1",
"list": [{
"sname": "sname1",
"svalue": "svalue1"
}, {
"sname": "sname2",
"svalue": "svalue2"
}]
}]
}
console.log(object.data[0].list[1].svalue)

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.

Dynamically add array elements to JSON Object

I'm creating a JSON object from an array and I want to dynamically push data to this JSON object based on the values from array. See my code for a better understanding of my problem...
for(i=0;i<duplicates.length; i++) {
var request = {
"name": duplicates[i].scope,
"id": 3,
"rules":[
{
"name": duplicates[i].scope + " " + "OP SDR Sync",
"tags": [
{
"tagId": 1,
"variables":[
{
"variable": duplicates[i].variable[j],
"matchType": "Regex",
"value": duplicates[i].scopeDef
}
],
"condition": false,
},
{
"tagId": 1,
"condition": false,
}
],
"ruleSetId": 3,
}
]
}
}
I take object properties from the duplicates array that can have the following elements:
[{scopeDef=.*, scope=Global, variable=[trackingcode, v1, v2]}, {scopeDef=^https?://([^/:\?]*\.)?delta.com/products, scope=Products Section, variable=[v3]}]
As you can see, an object contain variable element that can have multiple values. I need to push to the JSON object all those values dynamically (meaning that there could be more than 3 values in an array).
For example, after I push all the values from the duplicates array, my JSON object should look like this:
name=Products Section,
rules=
[
{
name=Products Section OP SDR Sync,
tags=[
{
variables=
[
{
matchType=Regex,
variable=v3,
value=^https?://([^/:\?]*\.)?delta.com/products
},
{
matchType=Regex,
variable=trackingcode,
value=.*
},
{
matchType=Regex,
variable=v1,
value=.*
},
{
matchType=Regex,
variable=v2,
value=.*
}
],
condition=false,
},
{
condition=false,
tagId=1
}
],
ruleSetId=3
}
]
}
I tried the following code but without success:
for(var j in duplicates[i].variable) {
var append = JSON.parse(request);
append['variables'].push({
"variable":duplicates[i].variable[j],
"matchType": "Regex",
"value": duplicates[i].scopeDef
})
}
Please let me know if I need to provide additional information, I just started working with JSON objects.
First of all, you dont need to parse request, you already create an object, parse only when you get JSON as string, like:
var json='{"a":"1", "b":"2"}';
var x = JSON.parse(json);
Next, you have any property of object wrapped in arrays. To correctly work with it you should write:
request.rules[0].tags[0].variables.push({
"variable":duplicates[i].variable[j],
"matchType": "Regex",
"value": duplicates[i].scopeDef
})
If you want to use your code snippet, you need some changes in request:
var request = {
"name": duplicates[i].scope,
"id": 3,
"variables":[
{
"variable": duplicates[i].variable[j],
"matchType": "Regex",
"value": duplicates[i].scopeDef
}
],
"rules":[
{
"name": duplicates[i].scope + " " + "OP SDR Sync",
"tags": [
{
"tagId": 1,
"condition": false,
},
{
"tagId": 1,
"condition": false,
}
],
"ruleSetId": 3,
}
]
}
}
To understand JSON remember basic rule: read JSON backward. It means:
property
object.property
arrayOfObfects['id'].object.property
mainObject.arrayOfObfects['id'].object.property
and so on. Good luck!

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.

Backbone .fetch() adds one too many models

I am using backbone's fetch method to retrieve a set of JSON from the server. Inside the fetch call, I have a success callback that correctly assigns attributes to a model for each object found.
var foo = assetCollection.fetch({
reset: true,
success: function(response){
var data = response.models[0].attributes.collection.items;
data.forEach(function(data){
assetCollection.add([
{src_href: data.data[0].value,
title: data.data[1].value
}
]);
});
console.log(assetCollection.models)
}
})
Right now I am working with a static set of JSON that has two objects. However, logging assetCollection.models returns three objects: the first is the initial server JSON response, while the next two are correctly parsed Backbone models.
How do I keep Backbone from adding the first object (the entire response from the server) to its set of models, and instead just add the two JSON objects that I am interested in?
The JSON object returned from the server is as follows:
{
"collection": {
"version": "1.0",
"items": [
{
"href": "http://localhost:8080/api/assets/d7070f64-9899-4eca-8ba8-4f35184e0853",
"data": [
{
"name": "src_href",
"prompt": "Src_href",
"value": "http://cdn.images.express.co.uk/img/dynamic/36/590x/robin-williams-night-at-the-museum-498385.jpg"
},
{
"name": "title",
"prompt": "Title",
"value": "Robin as Teddy Roosevelt"
}
]
},
{
"href": "http://localhost:8080/api/assets/d7070f64-9899-4eca-8ba8-4f35184e0853",
"data": [
{
"name": "src_href",
"prompt": "Src_href",
"value": "http://b.vimeocdn.com/ts/164/830/164830426_640.jpg"
},
{
"name": "title",
"prompt": "Title",
"value": "Mrs. Doubtfire"
}
]
}
]
}
}
You should modufy collection.
Probably you should change parse method:
yourCollection = Backbone.Collection.extend({
parse: function(data) {
return data.models[0].attributes.collection.items;
}
})
When you use fetch Backbone parse result and add all elements what you return in parse.

Categories

Resources