Dynamic array to JSON or Table to JSON - javascript

I've searched and attempted to get this working for a few weeks and I'm still failing. I've tried several ways including reg expressions. I have a dynamic table that I scrape with puppeteer and I'm trying to output that data as JSON. The problem is that the header "2nd flr (Rm 226)" & 'Location - Room 115' May or may not show. The events in these rooms may have 1 or multiple events. How do I convert dynamic data like this and ensure that I get everything listed?
I'm trying to get something like this JSON.
data: [
{
"location": "2nd flr (Rm 226)"
"time": "10:00 AM",
"description": "Social Security Administration Commissioner",
"document": "18",
"type": "Social Security Hearing",
"blank": " ",
"order": "Hearing"
},
{
"location": "2nd flr (Rm 226)"
"time": "01:00 PM",
"description:"
"Social Security Administration Commissioner",
"document": "18",
"type": "Order Setting Social Security Hearing",
"blank": " ",
order: "Hearing"
},
{
"location": "3rd flr (100)"
"time": "01:00 PM",
"description:"
"Social Security Administration Commissioner",
"document": "18",
"type": "Order Setting Social Security Hearing",
"blank": " ",
order: "Hearing"
}
]
const data = Array.from(
document.querySelectorAll('#content > table > tbody > tr'),
row => Array.from(row.querySelectorAll('td'), cell => cell.innerText)
)
Here is the output that I get.
{
"data": [
[
"2nd flr (Rm 226)"
],
[
"10:00 AM",
"Social Security Administration Commissioner",
"18",
"Social Security Hearing",
" ",
"Hearing"
],
[
"01:00 PM",
"Social Security Administration Commissioner",
"18",
"Order Setting Social Security Hearing",
" ",
"Hearing"
],
[
"3rd flr (100)"
],
[
"09:30 AM",
"TERMINATED on 03/23/2015",
"34",
"Resetting Hearings",
" ",
"Hearing"
],
[
" ",
"Reserved for case",
"23",
"Motion Hearing",
" ",
"Hearing"
],
[
"01:00 PM",
"Case Information",
"19",
"Order Setting",
" ",
"Hearing"
],
[
"01:30 PM",
"Case information",
"31",
"Order Setting",
" ",
"Hearing"
],
[
" ",
"TERMINATED on 06/14/2019",
"16",
"Order Setting/Resetting Hearings",
" ",
"Hearing"
],
[
"3rd flr (Rm 310)"
],
[
"01:30 PM",
"Insurance Company",
"122",
"Order Setting/Resetting Hearings",
" ",
"Hearing"
]
]
}
<center><Table border=1 width=98%>
<TR><TD id='report' class='report' align=center><B><FONT SIZE=+2>Daily Calendar Report of 09/23/2019</font></B><BR><CENTER></table></center>
<Table border=1 width=98% >
<TR><TD class='room' id='room' ALIGN=CENTER COLSPAN=6><STRONG>2nd flr (Rm 226)</STRONG></TD></TR>
<TR id='casedata' class='casedata'>
<TD class=case-0 id=case-0 VALIGN=top NOWRAP>10:00 AM</TD>
<TD class=case-1 id=case-1 VALIGN=top><A HREF=/Reportpt.pl?55244>Social Security Administration</A><B></B></TD>
<TD class=case-2 id=case-2 VALIGN=top>18</TD>
<TD class=case-3 id=case-3 VALIGN=top>Security Hearing</TD>
<TD class=case-4 id=case-4 VALIGN=top>&nbsp</TD>
<TD class=case-5 id=case-5 VALIGN=top NOWRAP><I>Hearing</I></TD>
</TR>
<TR><TD class='room' id='room' ALIGN=CENTER COLSPAN=6><STRONG>2nd flr (Rm 406)</STRONG></TD></TR>
<TR id='casedata' class='casedata'>
<TD class=case-0 id=case-0 VALIGN=top NOWRAP>1:30 PM</TD>
<TD class=case-1 id=case-1 VALIGN=top><A HREF=/Reportpt.pl?55244>Social Security Administration</A><B></B></TD>
<TD class=case-2 id=case-2 VALIGN=top>18</TD>
<TD class=case-3 id=case-3 VALIGN=top>Security Hearing</TD>
<TD class=case-4 id=case-4 VALIGN=top>&nbsp</TD>
<TD class=case-5 id=case-5 VALIGN=top NOWRAP><I>Hearing</I></TD>
</TR>
</table>
const tds = Array.from(document.querySelectorAll('#Content > table > tbody > tr > td'));
const trs = Array.from(document.querySelectorAll('#Content > table > tbody > tr'))
const data = Array.from(
document.querySelectorAll('#Content > table > tbody > tr'),
row => Array.from(row.querySelectorAll('td'), cell => cell.innerText),
data =>{ return ( [data] ) }
)

You need to look for further clues in your HTML to achieve the structure you desire. In this case I looked for the class of the first td in each tr.
[[ I know you are only reading the HTML, but it is faulty, as there are multiple identical ids assigned (room) in it ...]]
// define shortcut function qsa: querySelectorAll, returning a proper array
// An HTML context `el` can be given as an optional second parameter
function qsa(s,el){
return Array.prototype.map.call((el?Element:Document).prototype
.querySelectorAll.call((el||document),s),function(e){return e})
}
data=[];
qsa('tr').forEach(function(tr,i,arr){
var tds=qsa('td',tr);
if (tds[0].className=='room')
arr.room=tds[0].innerText // "remember" the current room data ...
else if (tds[0].className=='case-0')
data.push([arr.room].concat(tds.map(function(e){return e.innerText}))) // output room and row data
});
console.log(data)
// and, of course, the JSON is created by
var JSONdata=JSON.stringify(data);
<center><Table border=1 width=98%>
<TR><TD id='report' class='report' align=center><B><FONT SIZE=+2>Daily Calendar Report of 09/23/2019</font></B><BR><CENTER></table></center>
<Table border=1 width=98% >
<TR><TD class='room' id='room' ALIGN=CENTER COLSPAN=6><STRONG>2nd flr (Rm 226)</STRONG></TD></TR>
<TR id='casedata' class='casedata'>
<TD class=case-0 id=case-0 VALIGN=top NOWRAP>10:00 AM</TD>
<TD class=case-1 id=case-1 VALIGN=top><A HREF=/Reportpt.pl?55244>Social Security Administration</A><B></B></TD>
<TD class=case-2 id=case-2 VALIGN=top>18</TD>
<TD class=case-3 id=case-3 VALIGN=top>Security Hearing</TD>
<TD class=case-4 id=case-4 VALIGN=top>&nbsp</TD>
<TD class=case-5 id=case-5 VALIGN=top NOWRAP><I>Hearing</I></TD>
</TR>
<TR><TD class='room' id='room' ALIGN=CENTER COLSPAN=6><STRONG>2nd flr (Rm 406)</STRONG></TD></TR>
<TR id='casedata' class='casedata'>
<TD class=case-0 id=case-0 VALIGN=top NOWRAP>1:30 PM</TD>
<TD class=case-1 id=case-1 VALIGN=top><A HREF=/Reportpt.pl?55244>Social Security Administration</A><B></B></TD>
<TD class=case-2 id=case-2 VALIGN=top>18</TD>
<TD class=case-3 id=case-3 VALIGN=top>Security Hearing</TD>
<TD class=case-4 id=case-4 VALIGN=top>&nbsp</TD>
<TD class=case-5 id=case-5 VALIGN=top NOWRAP><I>Hearing</I></TD>
</TR>
</table>
This solution might seem a bit old-fashioned (no Array.from, no arrow functions). I wrote it so it will still work in IE.

I don't think that you have the right title. Getting json is easy, just use JSON.stringify Your problem is getting the objects you want to convert to be consistent, or at least the way you want them - it looks like the code is generating lots of arrays, rather than an array of objects
So I think you have to do more work parsing the html. I would console log the objects coming from the html to check it before converting to json.
So you could read each <td> explicitly, rather than in the loop, assigning either the value to the object or a default value

Related

JQuery Iterate through JSON and print into html

I have a JSON list, which can have an array of "OrderLines" , within this array is other data such as part number, price etc...
I want to be able to print/display each "OrderLine" and its data in some HTML elements/tags, for each order-line the HTML elements are to be repeated, meaning I don't want e.g. all Part-Numbers to be in the SAME div tag, hopefully the code below will make sense as to what I want to achieve
{
"Depot": 4,
"DocumentType": "Sales Order",
"DocumentNumber": "123",
"OrderDate": "2022-06-23T09:09:12+01:00",
"OrderReference": "TEST",
"OrderedBy": "",
"ContactName": "",
"AccountCode": "EXAMPLE",
"CustomerName": "EXAMPLE",
"CustomerAddress1": "EXAMPLE",
"CustomerAddress2": "EXAMPLE",
"CustomerAddress3": "EXAMPLE",
"CustomerAddress4": "EXAMPLE",
"DepotVATNumber": "GB EXAMPLE",
"DeliveryName": "EXAMPLE",
"DeliveryAddress1": "EXAMPLE",
"DeliveryAddress2": "EXAMPLE",
"DeliveryAddress3": "EXAMPLE",
"DeliveryAddress4": "EXAMPLE",
"OrderLines": [
{
"PartNumber": "EXAMPLE",
"Description": "EXAMPLE",
"IncludeCostCodes": false,
"MaterialCode": "0",
"CostCentre": "",
"Quantity": 2,
"Price": 9.5,
"TotalAmount": 19,
"VATRate": 20
}
{
"PartNumber": "EXAMPLE 2",
"Description": "EXAMPLE 2",
"IncludeCostCodes": false,
"MaterialCode": "0",
"CostCentre": "",
"Quantity": 0,
"Price": 0,
"TotalAmount": 0,
"VATRate": 0
}
],
"TotalGoods": 19,
"TotalVat": 3.8,
"GrandTotal": 22.8
}
JQuery
<script>
let order = #Html.Raw(Model.Content);
$('.billaddN').text(order.CustomerName + "," );
$('.billadd1').text(order.CustomerAddress1 + "," );
$('.billadd2').text(order.CustomerAddress2 + "," );
$('.billadd3').text(order.CustomerAddress3 + "," );
$('.billadd4').text(order.CustomerAddress4);
$('.shippadd1').text(order.DeliveryAddress1 + "," );
$('.shippadd2').text(order.DeliveryAddress2 + "," );
$('.shippadd3').text(order.DeliveryAddress3 + "," );
$('.shippadd4').text(order.DeliveryAddress4);
$('.shippaddN').text(order.DeliveryName + "," );
$('.ordRef').text(order.OrderReference);
$('.ordNo').text(order.DocumentNumber);
$('.ordDate').text(order.OrderDate);
$('.ordBy').text(order.OrderedBy);
$('.subtotal').text("£" + order.TotalGoods);
$('.totalvat').text("£" + order.TotalVat);
$('.total').text("£" + order.GrandTotal);
$('.vatNo').text(order.DepotVATNumber);
$('.accountNo').text(order.AccountCode);
$(order.OrderLines).each(function(i,e) {
$(".order-lines-container").append(
'<tr>
<td width="80%">
<span class="font-weight-bold">order.PartNumber[i]</span>
<div class="product-qty">
<span class="d-block">order.Description[i]</span>
<span>Color</span>
</div>
</td>
<td width="20%">
<div class="text-right">
<span class="font-weight-bold">order.Price[i]</span>
</div>
</td>
</tr>'
)});
</script>
Your code is almost there, the issue you have is that your each() loop doesn't reference the specific line in the array you're iterating through.
In addition, the looping code can be simplified and made more performant by using map() to create an array of strings which you then append to the DOM just once.
Here's a working example:
var order = {Depot:4,DocumentType:"Sales Order",DocumentNumber:"123",OrderDate:"2022-06-23T09:09:12+01:00",OrderReference:"TEST",OrderedBy:"",ContactName:"",AccountCode:"EXAMPLE",CustomerName:"EXAMPLE",CustomerAddress1:"EXAMPLE",CustomerAddress2:"EXAMPLE",CustomerAddress3:"EXAMPLE",CustomerAddress4:"EXAMPLE",DepotVATNumber:"GB EXAMPLE",DeliveryName:"EXAMPLE",DeliveryAddress1:"EXAMPLE",DeliveryAddress2:"EXAMPLE",DeliveryAddress3:"EXAMPLE",DeliveryAddress4:"EXAMPLE",OrderLines:[{PartNumber:"EXAMPLE",Description:"EXAMPLE",IncludeCostCodes:!1,MaterialCode:"0",CostCentre:"",Quantity:2,Price:9.5,TotalAmount:19,VATRate:20},{PartNumber:"EXAMPLE 2",Description:"EXAMPLE 2",IncludeCostCodes:!1,MaterialCode:"0",CostCentre:"",Quantity:0,Price:0,TotalAmount:0,VATRate:0}],TotalGoods:19,TotalVat:3.8,GrandTotal:22.8}
let rows = order.OrderLines.map(line => `
<tr>
<td width="80%">
<span class="font-weight-bold">${line.PartNumber}</span>
<div class="product-qty">
<span class="d-block">${line.Description}</span>
<span>Color</span>
</div>
</td>
<td width="20%">
<div class="text-right">
<span class="font-weight-bold">${line.Price}</span>
</div>
</td>
</tr>`);
$(".order-lines-container").append(rows);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<table class="order-lines-container"></table>

Vue.js not arranging elements numerically?

So I tried getting Vue.js to arrange elements numerically by using "sortBy".
Obviously, I failed. I searched the web but got no satisfactory results, so anybody could help me?
HTML (not the whole thing, just the table that Vue.js renders)
<table class="ui celled table">
<thead>
<tr>
<th #click="sortBy='name'">Name</th>
<th #click="sortBy='cal'">Caliber</th>
<th #click="sortBy='r'">Range (max-min)(studs)</th>
<th #click="sortBy='dmg'">Damage</th>
<th #click="sortBy='cap'">Capacity</th>
<th #click="sortBy='rpm'">Rate of Fire</th>
<th #click="sortBy='multi'">Damage Multiplier (Head/Torso)</th>
<th #click="sortBy='desc'">Description</th>
<th #click="sortBy='rank'">Rank Unlock</th>
</tr>
</thead>
<tbody>
<tr v-for="list in lists">
<td>{{list.name}}</td>
<td>{{list.cal}}</td>
<td>{{list.r}}</td>
<td>{{list.dmg}}</td>
<td>{{list.cap}}</td>
<td>{{list.rpm}}</td>
<td>{{list.multi}}</td>
<td>{{list.desc}}</td>
<td>{{list.rank}}</td>
</tr>
</tbody>
<tfoot>
<tr>
<th colspan="100%">{{sortedlists.length}} guns</th>
</tr>
</tfoot>
</table>
JS
new Vue({
el: "#main",
data: {
lists: [
{
"name": "M9",
"cal": "9×19mm",
"dmg": "35-10",
"cap": "15+1 / 105",
"rpm": "780",
"multi":"1.50/1.10",
"desc": "A 9mm Italian pistol. One of the first 'wonder nines'. High capacity with deep reserves, light recoil, and high velocity. ",
"r": "40-80",
"rank": "0"
},
{
"name": "GLOCK 17 (G17)",
"cal": "9×19mm",
"dmg": "34-10",
"cap": "17+1/102",
"rpm": "780",
"r":"40-90",
"multi":"1.50/1.10",
"desc": "A 9mm Austrian pistol renowned for its simplicity and ruggedness. Compared to the M9, it has a higher capacity, but less muzzle velocity.",
"rank": "1"
},
{
"name": "M1911",
"cal": ".45 ACP",
"dmg": "48-29",
"cap": "8+1/56",
"rpm": "720",
"r":"55-90",
"multi":"1.40/1.15",
"desc": "A classic American pistol brought into the modern age. Very high damage up close, with poor velocity and small magazine size.",
"rank": "2"
},
{
"name": "DESERT EAGLE (DEAGLE) L5",
"cal": ".44 MAGNUM",
"dmg": "56-32",
"cap": "8+1/40",
"rpm": "400",
"r":"50-80",
"multi":"2.00/ 1.30",
"desc": "A modern version of the iconic Israeli-American pistol. This specific model has been lightened as well as upgraded with dual Picatinny rails and a much-needed muzzle brake. Very high damage with the capacity to instantly kill to the head up close, with rough recoil.",
"rank": "3"
},
{
"name": "M45A1",
"cal": ".45 ACP",
"dmg": "45-28",
"cap": "10+1/60",
"rpm": "670",
"r":"50-95",
"multi":"1.40/1.15",
"desc": "A modern American pistol with many custom parts. High damage, medium capacity, strong recoil.",
"rank": "4"
},
{
"name": "FIVE SEVEN",
"cal": "5.7×28mm",
"dmg": "29-22",
"cap": "20+1/100",
"rpm": "800",
"r":"80-120",
"multi":"1.40/1.20",
"desc": "A modern Belgian pistol firing a unique caliber. Poor close-in performance, with great ranged performance, high velocity, large magazine, wall penetration and deep reserves.",
"rank": "5"
},
{
"name": "ZIP 22",
"cal": ".22 LONG RIFLE",
"dmg": "15-12",
"cap": "10+1/180",
"rpm": "1000 SEMI",
"r":"30-60",
"multi":"2.80/1.00",
"desc": "A modern American 'pistol' with questionable quality. Abysmal damage, but with deep reserves and a high headshot multiplier. A weapon so bad it killed a million dollar company. 3 shots to the head at all ranges.",
"rank": "6"
},
.
.
.
.
etc all the way to "rank": "100"
{
"name": "MG42**",
"cal": "7.62 NATO",
"dmg": "36-20",
"cap": "50/250",
"rpm": "1200 AUTO",
"multi":"1.40/1.00",
"desc": "The original, the iconic, the feared... The buzzsaw of the axis powers during the second world war, back to prove it’s worth in the modern warzone. Fires extremely fast and hits even harder, but is slow and inaccurate.",
"rank": "100"
},
],
sortBy: "rank",
filterByName: "",
counter: 0
},
computed: {
sortedlists() {
return this.lists.filter(
list => list.name.includes(this.filterByName)
).sort(
(a, b) => a[this.sortBy].localeCompare(b[this.sortBy])
);
}
}
});
EDIT: I didn't include the whole javascript so I thought I might as well update the questions to make it clearer. So as I said, the `
computed:
{
sortedlists() {
return this.lists.filter(
list => list.name.includes(this.filterByName)
).sort(
(a, b) => a[this.sortBy].localeCompare(b[this.sortBy])
);
}`
doesn't arrange the elements in numerical order.
etc. all the way to "rank": "100".
Vue arranges the elements in a way like 0,1,10,100,11,2,20,21........29,3,30,31,32,33,.....39,4,40,....48,49 etc
You get the idea. It just doesn't seem to arrange the elements like 1,2,3,4,5,6,7,8,9,10,11,12 etc. which I want it to do.
Any helpful answers?
You need to sort by rank as a number and not as a string. Alphabetical order is exact that you got: 1,10,100,11,2,20,21.
const sortedList = lists.splice().sort((x1, x2) => (parseInt(x1.rank) - parseInt(x2.rank)))
Ahhhh seems like I found the answer after some serious tinkering with the code.
I changed it to the following:
computed: {
sortedlists() {
return this.lists.filter(
list => list.name.includes(this.filterByName)
).sort(
(a, b) => a[this.sortBy] - b[this.sortBy]
);
}
}

How do I access and iterate array items by index in handlebars?

I need to iterate the JSON data in the handlebars in {{#each}} statement.
This is the JSON data,
{
"no": 0,
"address": "Here",
"name": "There",
"members": [
{
"email": "test#test.com",
"name": "SH",
"sex": "F"
},
{
"email": "test2#test.com",
"name": "SH2",
"sex": "F"
}],
"diary": [
{
"ddate":"0820",
"dcheck":"y"
},
{
"ddate":"0821",
"dcheck":"n"
}]
}
and this is the Handlebars code.
I need to iterate 1st, 2nd, 3rd... object's properties in the members list.
I want to know what to put in instead of [0].
{{#each list}}
<tr>
<td><a href='bd-view.html?email={{members.[0].email}}'>{{members.[0].email}}</a></td>
<td>{{members.[0].name}}</td>
<td>{{members.[0].sex}}</td>
<td>{{name}}</td>
<td>{{diary.[0].dcheck}}</td>
<td><input type="checkbox"></td>
</tr>
{{/each}}
This is my first question in stackoverflow.
Hope to see someone answer this question.
Thanks a lot, cheers.
You can use the following:
{{#each members}}
<tr>
<td><a href='bd-view.html?email={{email}}'>{{email}}</a></td>
<td>{{name}}</td>
<td>{{sex}}</td>
<td>{{name}}</td>
{{#with (lookup ../diary #index)}}
<td>{{dcheck}}</td>
{{/with}}
<td><input type="checkbox"></td>
</tr>
{{/each}}
Using the #each to iterate your array, and the function #lookup to access to relative position of the array diary
I actually upvoted Matheus answer using the with lookup of the index. however I did it a different way where I manipulate the data before passing it in.
for (var i = 0; i < data.members.length; i++) {
data.members[i].dcheck = data.diary[i].dcheck;
}
here is a fiddle
http://jsfiddle.net/N2b5M/6750/

DataTables not showing JSON data

Here is my HTML
<table id="dt">
<thead>
<tr>
<th>make</th>
<th>model</th>
<th>serial</th>
<th>status</th>
<th>User</th>
<th>dept</th>
<th>location</th>
</thead>
<tbody>
</tbody>
<tfoot></tfoot>
</table>
And here is my JS
<script type="text/javascript" language="javascript" >
$(document).ready(function() {
$.post("json.php",function(data){
$('#dt').DataTable( {
"aaData": data,
"aoColumns": [
{"mDataProp": "make"},
{"mDataProp": "model"},
{"mDataProp": "serial"},
{"mDataProp": "status"},
{"mDataProp": "user"},
{"mDataProp": "dept"},
{"mDataProp": "location"}
]
});
});
} );
</script>
And here is json.php
$data = Array ();
$data[] = array("make" => "Hp", "model" => "jhbh", "serial" => "kjkhn", "status" => "active", "user" => "John Doe", "dept" => "Manufacturing Services", "location" => "Bindura");
$data[] = array("make" => "Dell", "model" => "Vostro", "serial" => "kjkhn", "status" => "active", "user" => "Percy Holdin", "dept" => "Manufacturing Services", "location" => "Kwekwe");
echo json_encode($data,JSON_PRETTY_PRINT);
I have made an edit to this question, because now I want to get dyanmic data.
Error:
DataTables warning: table id=dt - Requested unknown parameter 'make' for row 0, column 0. For more information about this error, please see http://datatables.net/tn/4
But I havent found anything useful from that help link
JSON format should be like this as in this example: https://datatables.net/examples/data_sources/ajax.html
{
"data": [
[
"Hp",
"jhbh",
"kjkhn",
"active",
"John Doe",
"Manufacturing Services",
"Bindura"
]
]
}
Example on how to format json like this in php(well, one way):
$data = (object) [
'data' => [[
'test',
'test',
'test'
]]
];
echo json_encode($data);
And live example: http://sandbox.onlinephpfunctions.com/code/632c288c6c743da25e49958c204a8d4e0a936b54
you JSON should only be:
[
{
"make":"Hp",
"model":"jhbh",
"serial":"kjkhn",
"status":"active",
"user":"John Doe",
"dept":"Manufacturing Services",
"location":"Bindura"
}
]
You data should like below:
{
"data": [
[
"Hp",
"jhbh",
"kjkhn",
"active",
"John Doe",
"Manufacturing Services",
"Bindura"
]
]
}
As others already mentionned in the comments, dataTables need a specific HTML-Structure of the table.
Look at the examples at the Docs:
https://datatables.net/examples/basic_init/zero_configuration.html
Table should look like this:
<table id="example" class="display">
<thead>
<tr>
<th>Name</th>
<th>Position</th>
<th>Office</th>
<th>Age</th>
<th>Start date</th>
<th>Salary</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
EDIT: Maybe this requirement is outdated. Seems that dataTables can insert the tbody-tag on its own now
And the returned jsonData should have a structure like this
https://datatables.net/examples/ajax/simple.html
{
"data": [
[
"Hp",
"jhbh",
"kjkhn",
"active",
"John Doe",
"Manufacturing Services",
"Bindura"
]
]
}
I was getting JSON from PHP:
echo json_encode($arr);
Array was missing some keys, like: 1,2,3,10,122...
Because of missing keys, dataTable plugin won't display data inside table.
So I changed code like so:
array_multisort($arr);
echo json_encode($arr);
after multisort, keys are reset, and there should not be any missing key.

Using each in PHP like jquery

I'm used to using jQuery's each to go through an array and now I need to do the same in PHP, but I'm not quite sure how. PHP's each doesn't work quite the same way.
Given the following array, I know in jquery I could do something like the following to get the id value from each of the entry fields:
$.each(obj.entry, function(i, data) {
console.log(data.id);
});
The question I have is how to do this same thing in PHP. I tried:
//code to generate `$json` up here
echo $json; //returns array shown below
$newarray =json_decode($json, true);
$broke = each($newarray);
What do I need to do differently to get all the id from all the entries? Assume there will be around 100 or so.
Example JSON object below:
{
"id": "https://itunes.apple.com/us/rss/toppodcasts/limit=2/explicit=true/xml",
"title": "iTunes Store: Top Podcasts",
"updated": "2016-02-11T07:26:05-07:00",
"link": [{
"#attributes": {
"rel": "alternate",
"type": "text/html",
"href": "https://itunes.apple.com/WebObjects/MZStore.woa/wa/viewTop?cc=us&id=38&popId=3"
}
}, {
"#attributes": {
"rel": "self",
"href": "https://itunes.apple.com/us/rss/toppodcasts/limit=2/explicit=true/xml"
}
}],
"icon": "http://itunes.apple.com/favicon.ico",
"author": {
"name": "iTunes Store",
"uri": "http://www.apple.com/itunes/"
},
"rights": "Copyright 2008 Apple Inc.",
"entry": [{
"updated": "2016-02-11T07:26:05-07:00",
"id": "https://itunes.apple.com/us/podcast/serial/id917918570?mt=2&uo=2",
"title": "Serial - This American Life",
"summary": "Serial is a podcast from the creators of This American Life, hosted by Sarah Koenig. Serial unfolds one story - a true story - over the course of a whole season. The show follows the plot and characters wherever they lead, through many surprising twists and turns. Sarah won't know what happens at the end of the story until she gets there, not long before you get there with her. Each week she'll bring you the latest chapter, so it's important to listen in, starting with Episode 1. New episodes are released on Thursday mornings.",
"link": {
"#attributes": {
"rel": "alternate",
"type": "text/html",
"href": "https://itunes.apple.com/us/podcast/serial/id917918570?mt=2&uo=2"
}
},
"category": {
"#attributes": {
"term": "News & Politics",
"scheme": "https://itunes.apple.com/us/genre/podcasts-news-politics/id1311?mt=2&uo=2",
"label": "News & Politics"
}
},
"rights": "© Copyright 2016 Serial Podcast",
"content": "<table border=\"0\" width=\"100%\">\n <tr>\n <td>\n <table border=\"0\" width=\"100%\" cellspacing=\"0\" cellpadding=\"0\">\n <tr valign=\"top\" align=\"left\">\n \n <td align=\"center\" width=\"166\" valign=\"top\">\n <img border=\"0\" alt=\"This American Life - Serial artwork\" src=\"http://is2.mzstatic.com/image/thumb/Podcasts69/v4/90/ef/70/90ef704d-a2d6-ca6f-6972-1b62f8eadb01/mza_7676577196916555630.png/170x170bb-85.jpg\" />\n </td>\n <td width=\"10\"><img alt=\"\" width=\"10\" height=\"1\" src=\"https://s.mzstatic.com/images/spacer.gif\" /></td>\n \t<td width=\"95%\">\n \n \n <b>Serial</b><br/>\n \n \n \n \n\n This American Life\n\n <font size=\"2\" face=\"Helvetica,Arial,Geneva,Swiss,SunSans-Regular\">\n\t\t\t\t\t\t\n\t\t\t\t\t\t \t<br/>\n <b>Genre:</b> News & Politics\n \n\t\t\t\t\t\t \t<br/>\n <b>Release Date:</b> February 6, 2016\n \n </font>\n </td>\n </tr>\n </table>\n </td>\n </tr>\n <tr>\n <td>\n \n <font size=\"2\" face=\"Helvetica,Arial,Geneva,Swiss,SunSans-Regular\"><br/>Serial is a podcast from the creators of This American Life, hosted by Sarah Koenig. Serial unfolds one story - a true story - over the course of a whole season. The show follows the plot and characters wherever they lead, through many surprising twists and turns. Sarah won't know what happens at the end of the story until she gets there, not long before you get there with her. Each week she'll bring you the latest chapter, so it's important to listen in, starting with Episode 1. New episodes are released on Thursday mornings.</font><br/>\n \n \n \n <font size=\"2\" face=\"Helvetica,Arial,Geneva,Swiss,SunSans-Regular\"> © © Copyright 2016 Serial Podcast</font>\n\t \n </td>\n </tr>\n</table>\n"
}, {
"updated": "2016-02-11T07:26:05-07:00",
"id": "https://itunes.apple.com/us/podcast/real-crime-profile/id1081244497?mt=2&uo=2",
"title": "Real Crime Profile - Real Crime Profile",
"summary": "Podcast talking about criminal cases and personality profiling.",
"link": {
"#attributes": {
"rel": "alternate",
"type": "text/html",
"href": "https://itunes.apple.com/us/podcast/real-crime-profile/id1081244497?mt=2&uo=2"
}
},
"category": {
"#attributes": {
"term": "History",
"scheme": "https://itunes.apple.com/us/genre/podcasts-history/id1462?mt=2&uo=2",
"label": "History"
}
},
"rights": "© All rights reserved",
"content": "<table border=\"0\" width=\"100%\">\n <tr>\n <td>\n <table border=\"0\" width=\"100%\" cellspacing=\"0\" cellpadding=\"0\">\n <tr valign=\"top\" align=\"left\">\n \n <td align=\"center\" width=\"166\" valign=\"top\">\n <img border=\"0\" alt=\"Real Crime Profile - Real Crime Profile artwork\" src=\"http://is5.mzstatic.com/image/thumb/Podcasts69/v4/ff/fa/95/fffa95d2-5156-2f85-8e2e-1b2bc3a82236/mza_1683998348979602855.jpg/170x170bb-85.jpg\" />\n </td>\n <td width=\"10\"><img alt=\"\" width=\"10\" height=\"1\" src=\"https://s.mzstatic.com/images/spacer.gif\" /></td>\n \t<td width=\"95%\">\n \n \n <b>Real Crime Profile</b><br/>\n \n \n \n \n\n Real Crime Profile\n\n <font size=\"2\" face=\"Helvetica,Arial,Geneva,Swiss,SunSans-Regular\">\n\t\t\t\t\t\t\n\t\t\t\t\t\t \t<br/>\n <b>Genre:</b> History\n \n\t\t\t\t\t\t \t<br/>\n <b>Release Date:</b> February 2, 2016\n \n </font>\n </td>\n </tr>\n </table>\n </td>\n </tr>\n <tr>\n <td>\n \n <font size=\"2\" face=\"Helvetica,Arial,Geneva,Swiss,SunSans-Regular\"><br/>Podcast talking about criminal cases and personality profiling.</font><br/>\n \n \n \n <font size=\"2\" face=\"Helvetica,Arial,Geneva,Swiss,SunSans-Regular\"> © © All rights reserved</font>\n\t \n </td>\n </tr>\n</table>\n"
}]
}
foreach($newarray as $key => $value) {
echo $key; // 0, 1, 2, etc
echo $value['id'] ; // echos ID
}
As your JSON String represents an object I would leave it as an object i.e. loose the ,true in the json_decode()
$jObj = json_decode($json);
foreach( $jObj->entry as $entry ) {
echo $entry->id . PHP_EOL;
echo $entry->title . PHP_EOL;
echo $entry->updated . PHP_EOL;
}
To make a new object out of what you take from the original data you coudl do something like this
$jObj = json_decode($json);
$new = new stdClass(); // create a new object
foreach( $jObj->entry as $entry ) {
$t = new stdClass();
$t->id = $entry->id;
$t->title = $entry->title;
$t->updated = $entry->updated;
$new->entries[] = $t; // create an array of objects
}
$newJsonString = json_encode($new);
PHP has foreach for this kind of operation
foreach($data as $key=> $value){
echo $value['id'];// or whatever you need
}
You can use php foreach loop:
foreach($newarray as $key => $value) {
// do smthg here
}
You can use for and foreach statements.
$row = json_decode($jsonString);
foreach($row as $key => $value) {
echo $key, '=>', $value;
// for you in $value will be key id $value['id']
}

Categories

Resources