jQuery how to implement nested $.each() in DataTables - javascript

I get Json data from server in order to display information by using DataTables.
In this json, there are rows, where in a column there may exist more than one value, so it's a multidimensional array as follows (I show just an excerpt of the array):
{
"info_table": [
{
"date": "2015-01-06",
"subject": "Some subject or title",
"type": "article",
"url": null,
"pdf": null,
"notes": null,
"created_at": "2015-06-26 13:38:53",
"updated_at": "2015-06-26 13:38:53",
"institute": "Some Institute name",
"researchers": [
{
"name": "CARL SMITH"
}
],
"assistants": [
{
"name": "YULIA SMIRNOVA"
}
]
}
]
}
The DataTable works fine so far:
$('#notes_table table').append('<thead><tr><th>Researchers</th><th>Date</th></tr></thead><tbody></tbody>');
$.each(response.info_table,function(i,item){
$('#notes_table').find('tbody').append('<tr><td>'+item.researchers+'</td><td>'+item.date+'</td></tr>');
});
The date column values are displayed fine, however, for the researcherscolumn only [object Object] is displayed. If I try to use a nested $.each() as follows:
$('#notes_table table').append('<thead><tr><th>Researchers</th><th>Date</th></tr></thead><tbody></tbody>');
$.each(response.info_table,function(i,item){
$.each(item.researchers, function(j,item2){
$('#notes_table').find('tbody').append('<td>'+item2.name+'</td>');
});
$('#notes_table').find('tbody').append('<td>'+item.date+'</td>');
});
I don't get anything, I just see a DataTables message saying Sorry, no results found.
What am I missing? Any ideas?
Solution
Thanks to BLSully:
The working code looks as follows:
var table = $('#table_id').DataTable({
columns: [{
data: 'researchers[, ].name',
title: 'Researchers'
}, {
data: 'date',
title: 'Date'
}]
});
table.rows.add(data).draw();
And that was it.

I'm assuming based on your wording, you're using datatables. Given that, I'm going to provide an alternate example of handling databinding to your table that utilizes the design of the plugin rather than manual DOM manipulation. So.. this isn't exactly an answer to the question, but rather a suggestion of the proper way of doing what you're trying to achieve (given the context you've provided. Depending on how your retrieving your data, there may be some slight changes)
The correct way to add orthogonal json data to your table is by creating column definitions so the table knows which columns to display your data, along with rules around how it's to be displayed.
I set up an example based on your data (expanded a bit to explain how to deal with deeply nested objects and arrays). The really relevant bit is the data property on the first column: researchers[, ].name. The syntax of that value instructs datatables to treat the property researchers as an array, and displaying it in a comma-separated fashion. Because the array elements are JavaScript objects, the .name following the square brackets instructs DataTables on which property of the object should be displayed.
http://live.datatables.net/domivewi/1/
var data = [
{
"date": "2015-01-06",
"subject": "Some subject or title",
"type": "article",
"url": null,
"pdf": null,
"notes": null,
"created_at": "2015-06-26 13:38:53",
"updated_at": "2015-06-26 13:38:53",
"institute": "Some Institute name",
"researchers": [{
"name": "CARL SMITH"
},{
"name": "JOHN DOE"
}],
"assistants": [
{
"name": "YULIA SMIRNOVA"
}
]
},{
"date": "2015-01-06",
"subject": "Some subject or title",
"type": "article",
"url": null,
"pdf": null,
"notes": null,
"created_at": "2015-06-26 13:38:53",
"updated_at": "2015-06-26 13:38:53",
"institute": "Some Institute name",
"researchers": [{
"name": "FRED FLINSTONE"
},{
"name": "WILMA FLINTSTONE"
}],
"assistants": [
{
"name": "BARNEY RUBBLE"
}
]
}
];
var table = $('#demo').DataTable({
columns: [{
//this is the important bit here. See explanation above
data: 'researchers[, ].name',
title: 'Researchers'
}, {
data: 'date',
title: 'Date'
}]
});
//this line adds new rows to the table and redraws
table.rows.add(data).draw();
body {
font: 90%/1.45em "Helvetica Neue", HelveticaNeue, Verdana, Arial, Helvetica, sans-serif;
margin: 0;
padding: 0;
color: #333;
background-color: #fff;
}
div.container {
min-width: 980px;
margin: 0 auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!DOCTYPE html>
<html>
<head>
<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
<link href="//datatables.net/download/build/nightly/jquery.dataTables.css" rel="stylesheet" type="text/css" />
<script src="//datatables.net/download/build/nightly/jquery.dataTables.js"></script>
<meta charset=utf-8 />
<title>DataTables - JS Bin</title>
</head>
<body>
<table id="demo"></table>
</body>
</html>

Try This ...
First of all save the json string in javascript array.
Like this ...
var myArray = Array();
myArray = {
"info_table": [
{
"date": "2015-01-06",
"subject": "Some subject or title",
"type": "article",
"url": null,
"pdf": null,
"notes": null,
"created_at": "2015-06-26 13:38:53",
"updated_at": "2015-06-26 13:38:53",
"institute": "Some Institute name",
"researchers": [
{
"name": "CARL SMITH"
}
],
"assistants": [
{
"name": "YULIA SMIRNOVA"
}
]
}
]
}
// Then Execute like this ..
$('#notes_table table').append('<thead><tr><th>Researchers</th><th>Date</th></tr></thead><tbody></tbody>');
$.each(myArray.info_table,function(i,item){
for( var i; i < item.researchers.length, i++){
$('#notes_table').find('tbody').append('<td>'+item.researchers[i].name+'</td>');
});
$('#notes_table').find('tbody').append('<td>'+item.date+'</td>');
});

Related

Node.js parse non-standard hast data to HTML?

How can we convert non-standard hast (which is parsed from a Markdown file) to HTML?
For example, this is the HTML tree data I have:
{
"_path": "/hello",
"_draft": false,
"_partial": false,
"_empty": false,
"title": "Hello!",
"description": "",
"body": {
"type": "root",
"children": [
{
"type": "element",
"tag": "h1",
"props": {
"id": "hello!"
},
"children": [
{
"type": "text",
"value": "Hello!"
}
]
}
],
"toc": {
"title": "",
"searchDepth": 2,
"depth": 2,
"links": []
}
},
"_type": "markdown",
"_id": "content:hello.md",
"_source": "content",
"_file": "hello.md",
"_extension": "md"
}
How can I parse that 'body' bit to HTML in Node.js?
I tried to use hast-util-to-html:
import { toHtml } from 'hast-util-to-html'
console.log('data.body =', toHtml(data.body))
But I got the following error:
TypeError: Cannot read properties of undefined (reading 'toLowerCase')
I think the tag key in the data should be tagName for using hast-util-to-html. tag and prop are non-standard keys I suppose, how can I standardise them?

Manipulating nested objects

I have the following data structure:
{
"nodes": [
{
"frontmatter": {
"excerpt": null,
"featured": true,
"title": "A Post with Content"
},
"fields": {
"slug": "posts/a-post-of-type-page",
}
},
{
"frontmatter": {
"excerpt": null,
"featured": null,
"title": "A post of type post"
},
"fields": {
"slug": "posts/a-post-of-type-post",
}
},
{
"frontmatter": {
"excerpt": null,
"featured": null,
"title": "Another Post (or type post)"
},
"fields": {
"slug": "posts/another-post-or-type-post",
}
},
{
"frontmatter": {
"excerpt": "This is the excerpt of a post",
"featured": null,
"title": "With Content"
},
"fields": {
"slug": "posts/with-content",
}
},
]
}
I know that I can use myObject.nodes.map(x => x.frontmatter) to bring the frontmatter up a level and removing the nesting. But, I now need to change each node into the following structure within the resulting array:
{
"nodes": [
{
"excerpt": null,
"featured": true,
"title": "A Post with Content"
"slug": "posts/a-post-of-type-page",
},
...
]
}
So, I need to remove the nesting for both the frontmatter and fields.
Thanks
const d = {"nodes":[{"frontmatter":{"excerpt":null,"featured":true,"title":"A Post with Content"},"fields":{"slug":"posts/a-post-of-type-page"}},{"frontmatter":{"excerpt":null,"featured":null,"title":"A post of type post"},"fields":{"slug":"posts/a-post-of-type-post"}},{"frontmatter":{"excerpt":null,"featured":null,"title":"Another Post (or type post)"},"fields":{"slug":"posts/another-post-or-type-post"}},{"frontmatter":{"excerpt":"This is the excerpt of a post","featured":null,"title":"With Content"},"fields":{"slug":"posts/with-content"}}]};
d.nodes = d.nodes.map(({frontmatter, fields})=>({...frontmatter, ...fields}));
console.log(d);
Here is another solution:
const data = {"nodes":[{"frontmatter":{"excerpt":null,"featured":true,"title":"A Post with Content"},"fields":{"slug":"posts/a-post-of-type-page"}},{"frontmatter":{"excerpt":null,"featured":null,"title":"A post of type post"},"fields":{"slug":"posts/a-post-of-type-post"}},{"frontmatter":{"excerpt":null,"featured":null,"title":"Another Post (or type post)"},"fields":{"slug":"posts/another-post-or-type-post"}},{"frontmatter":{"excerpt":"This is the excerpt of a post","featured":null,"title":"With Content"},"fields":{"slug":"posts/with-content"}}]};
let newArr = [];
data.nodes.forEach((n)=>newArr.push(Object.assign(n.fields, n.frontmatter)));
console.log({"nodes": newArr});

Accessing a value of an Object in an Array nested in an Object with Polymer

I am sorry for this unclear title
The Problem
I have a data Object with an Array of contacts that holds several Objects inside it. Unfortunately I am unable to access the value's of the nested Object.
A answer to a similar question found here explains how to access it in JavaScript. response.data.contacts[1].value However, using Polymer just prints the code instead of retrieving the value. I believe that the problem comes from the square brackets I use inside my binding. {{response.data.contacts[1].value}}
Below I added my data to clarify what I mean by value of object inside an object with an array as this is a bit confusing. I want to access just the value inside the contacts array and not iterate over all of them
{
"data": {
"contacts": [
{
"id": 259,
"user_id": 248,
"type": "phone",
"value": "+1 (946) 315-2819",
"created_at": "2016-08-24 18:12:30",
"updated_at": "2016-10-24 13:03:33",
"deleted_at": null
},
{
"id": 260,
"user_id": 248,
"type": "phone",
"value": "+1-979-427-7971",
"created_at": "2015-12-08 04:10:19",
"updated_at": "2016-10-24 13:03:33",
"deleted_at": null
},
]
},
}
To bind to a subproperty of an array item, use an array item path like this:
{{response.data.contacts.1.value}}
HTMLImports.whenReady(() => {
"use strict";
Polymer({
is: 'x-foo',
properties: {
response: {
type: Object,
value: () => ({
"data": {
"contacts": [{
"id": 259,
"user_id": 248,
"type": "phone",
"value": "+1 (946) 315-2819",
"created_at": "2016-08-24 18:12:30",
"updated_at": "2016-10-24 13:03:33",
"deleted_at": null
}, {
"id": 260,
"user_id": 248,
"type": "phone",
"value": "+1-979-427-7971",
"created_at": "2015-12-08 04:10:19",
"updated_at": "2016-10-24 13:03:33",
"deleted_at": null
}, ]
},
})
}
}
});
});
<head>
<base href="https://polygit.org/polymer+1.7.0/components/">
<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link rel="import" href="polymer/polymer.html">
</head>
<body>
<x-foo></x-foo>
<dom-module id="x-foo">
<template>
<span>{{response.data.contacts.1.value}}</span>
</template>
</dom-module>
</body>
codepen

displaying nested json in ng-repeat

I seem to be having difficulty in grasping how to drill down to get to nested JSON and display it on a page using angular. For example I have the following JSON structure and I want to display the connectivity products under portfolio in an ng-repeat...
{
"addons": [
...
],
"attributes": [
...
],
"portfolios": [
{
"connectivity": [
{
"product-1": {
"label": "product-1",
"description": "Description in here"
}
},
{
"product-2": {
"label": "product-2",
"description": "Description in here"
}
}
]
}
]
}
So far I have tried it two different ways.
$scope.listOfProducts = allProducts.data.portfolios.connectivity;
and in the ng-repeat
ng-repeat='product in listOfProducts.portfolios.connectivity'
What would be the correct way to loop through and display the 'connectivity' products in a ng-repeat? Thanks
EDIT:
I've changed the JSON to this structure...
{
"addons": [
...
],
"attributes": [
...
],
"portfolios": [
{
"connectivity": [
{
"label": "product-1",
"description": "Description in here"
},
{
"label": "product-2",
"description": "Description in here"
}
]
}
]
But I still can't seem to get ng-repeat to display the products in connectivity.
$scope.listOfProducts = allProducts.data.portfolios.connectivity
Since listOfProducts is already set to the connectivity array, you would just ng-repeat="product in listOfProducts"
<div ng-repeat="product in listOfProducts">
{{product.label}}
</div>
Edit: Well, your array is sort of irregular, since you're creating a property called product-[index] for each item. Do you have control of the data which is returned? Your array should just have the objects, like:
"connectivity": [
{
"label": "product-1",
"description": "Description in here"
},
{
"label": "product-2",
"description": "Description in here"
}
]

Iterate through nested Javascript Objects from API response

I've tried 100 different things, and spend days looking through Google and Stackoverflow, but I can't find a solution to this problem. Everything I call after the body of this API response returns undefined!
The response from Facebook SDK looks like this:
[
{
"body": "[
"data": [
{
"name": "Larry Syid Wright",
"administrator": false,
"id": "xxx"
}, {
"name": "Melissa Long Jackson",
"administrator": false,
"id": "xxx"
}, {
"name": "Charlotte Masson",
"administrator": false,
"id": "xxx"
}
],
"paging": {
"next": "url"
}
]"
},{
"body": "{
"data": [
{
"id": "xxx_xxx",
"message": "In honor of Halloween, how many of you have your own ghost stories? Who believes in ghosts and who doesn't?",
"type": "status",
"created_time": "2014-10-31T20:02:01+0000",
"updated_time": "2014-11-01T02:52:51+0000",
"likes": {
"data": [
{
"id": "xxx",
"name": "Joe HerBatman Owenby Jr."
}
],
}
"paging": {
"cursors":
{
"after": "xxx",
"before": "xxx"
}
}
}
},{
"id": "xxx_xxx",
"from": {
"id": "xxx",
"name": "Jessica Starling"
},
"message": "Watching the "Campaign" and I can't help but notice what a fantastic job they did (Will ferrell and all) with that North Carolina accent! Ya'll know we sound different than other southern states ;)",
"type": "status",
"created_time": "2014-11-01T02:36:21+0000",
"updated_time": "2014-11-01T02:36:21+0000",
"likes": {
"data": [
{
"id": "xxx",
"name": "Scott Williams"n
}
]
}
}
],
"paging": {
"previous": "xxx",
"next": "xxx"
}
}"
}
]
This response is from a batch call. If I call them separately, I can easily iterate through the responses, and get everything from them. When I call them in the batch though, I can't get past "body", and I need to use a batch call.
console.log(response[0].body); will return the object inside the body of the first part of the response, but console.log(response[0].body.data); returns undefined. I just don't get it. This should be simple but it's like there's a lock on the door and I don't have the right key.
I normally have no issue iterating through objects, so I don't need a generalized answer. I need help seeing whatever it is here that I don't see. Why does the console show undefined when I call anything after the body, and what do I need to be doing to get any of these values?
That JSON contains nested JSON. body seems to be a string. Use
var body = JSON.parse(response[0].body);
The values from the body are just strings.which are embedded as json.So firstly you would need to parse them using JSON.parse.
The code would be like
var body = JSON.parse(response[0].body);

Categories