Cant load this JSON into my table - javascript

I 've got a simple thing:
There's a JSON with books objects,every book has a title,author and year.
I would like to choose one option from the list and display chosen property in a table.I've used an example from W3 but right now i'm stuck and nothing works as it should...
Link's here
function change_myselect(sel) {
var obj, dbParam, xmlhttp, myObj, x, txt = "";
obj = { "table":sel, "limit":20 };
dbParam = JSON.stringify(obj);
xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
myObj = JSON.parse(this.responseText);
txt += "<table border='1'>"
for (x in myObj) {
txt += "<tr><td>" + myObj[x].name + "</td></tr>";
}
txt += "</table>"
document.getElementById("demo").innerHTML = txt;
}
};
xmlhttp.open("GET", "generated.json", true);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlhttp.send("x=" + dbParam);
}

The problem is quite easy to spot with a debugger line
console.log(myObj)
It is an object and you are trying to loop over it. You want to be looping over the key in the object that holds the array.
console.log(myObj.books);

You are iterating over a single property books in an object instead of iterating over the array that property contains.
Instead of this:
for (x in myObj) {
txt += "<tr><td>" + myObj[x].name + "</td></tr>";
}
try something like this:
myObj.books.forEach((book) => {
txt += "<tr><td>" + book[sel.toLowerCase()] + "</td></tr>";
});

Related

Cell Popup with data from custom data source

I am trying to make tabulator to show clickPopup with data that comes with additional http-request. Here is the definition of certain column, which calls cellPopupFormatterVV function:
{title:"WSCReportVolumes", field:"WSCReportVolumes.ErrorShort",
mutator:mutatorNoData,
clickPopup:cellPopupFormatterVV
},
Here is function itself:
var cellPopupFormatterVV = function(e, cell, onRendered){
var cellContent = cell.getData();
var data = handlerCellPopup();
var container = document.createElement("div");
var contents = "<strong style='font-size:1.2em;'>Status details</strong><br/><ul style='padding:0; margin-top:10px; margin-bottom:0;'>";
contents += "<li><strong>Error:</strong> " + data.ErrorShort + "</li>";
contents += "<li><strong>Error Code:</strong> " + data.ErrorCode + "</li>";
contents += "<li><strong>Error Description:</strong> " + data.ErrorLong + "</li>";
contents += "<li><strong>Failed Check:</strong> " + data.FunctionName + "</li>";
contents += "<li><strong>Result:</strong> " + data.ShortMsg + "</li>";
contents += "</ul>";
container.innerHTML = contents;
return container;
};
I'm trying to get data through function handlerCellPopup() which is in separate file "controller_ajax.js":
<script type="text/javascript" src="controller_ajax.js"></script>
The function itself:
function handlerCellPopup() {
const xhttp = new XMLHttpRequest();
xhttp.onload = function() {
let Response = xhttp.response;
return (Response);
};
xhttp.open("GET", "http://localhost:8003/ajax?cellPopup=rov_WSCReportVolumes_Last&computerName=ALAV706", true);
xhttp.responseType = 'json';
xhttp.send();
}
When I do request through browser, it returns exactly what I expect:
[{"ErrorLong":"Free disk space is low","ExecCode":1,"ErrorShort":"Warning","FunctionName":"Check-IsVolumeLowSpace","ErrorCode":201,"ShortMsg":"C:\\"}]
But if I try to click cell in tabulator no popup is shown. I think there is a problem with handlerCellPopup() but no idea how should I change function. Please, help.

parse line-separated json objects in html table

I can't change json format. The data store in new line.
json file:
{"ProgMode":"on","wait_h":"5","wait_m":"5","output":"1"}
{"ProgMode":"off","wait_h":"10","wait_m":"10","output":"2"}
I using below code but without bracket ([]) in json file, it doesn't work.
var ReqJson = new XMLHttpRequest();
function response(){
if(this.readyState == 4 && this.status == 200){
var myObj = JSON.parse(this.responseText);
const dbParam = JSON.stringify({table:"ProgramView",limit:20});
let text = "<table class='table my-0'>"
for (let x in myObj) {
text += '<tr><td>' + myObj[x].wait_h + ':' + myObj[x].wait_m + ':' + myObj[x].output + '</td></tr>';
}
text += "</table>"
document.getElementById("dynamic_table").innerHTML = text;
}
}
function ProccessConfig(){
ReqJson.open("POST", "Programs.json", true);
ReqJson.onreadystatechange = response;
ReqJson.send()
}
ProccessConfig();
So how can I parse json that is stored with new lines and without comma and brackets?
You can split the input text in rows and then 'JSON.parse' the single row.
let myObj = this.responseText.split('\n')
.filter(line => line !== "")
.map(JSON.parse);
Example based on your string:
let text = `{"ProgMode":"on","wait_h":"5","wait_m":"5","output":"1"}
{"ProgMode":"off","wait_h":"10","wait_m":"10","output":"2"}
`
let myObj = text.split('\n')
.filter(line => line !== "")
.map(JSON.parse);
console.log(myObj)
you don't need to split and map, it is to heavy for this case, try this
var myObj = JSON.parse(`[${this.responseText.replaceAll("}\n","},")}]`);
this is a little more complicated, but much more reliable,since it is not using any special symbols
var myObj = JSON.parse(`[{${this.responseText.substring(1).replaceAll("{",",{")}]`);

Table data from api

I'm trying to get my data from the API into the table.
I've tried loops but it won't work
var obj, dbParam, xmlhttp, myObj, x, txt = "";
obj = { table: "login", limit: 20 };
dbParam = JSON.stringify(obj);
xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
myObj = JSON.parse(this.responseText);
txt += "<table border='1'>"
for (x in myObj) {
txt += "<tr><td>" +myObj[x].name+ "</tr></td>";
}
txt += "</table>"
document.getElementById("myData").innerHTML = txt;
console.log(JSON.parse(this.responseText));
}
};
xmlhttp.open("GET", "https://api.github.com/users", true);
xmlhttp.setRequestHeader("Content-type", "application//x-www-form-urlencoded");
xmlhttp.send("x="+dbParam);
I would like for the table to be filled with the API data
You are closing the <tr> before the <td>:
txt += "<tr><td>" +myObj[x].name+ "</tr></td>";
fix:
txt += "<tr><td>" +myObj[x].name+ "</td></tr>";
Try this:
var obj, dbParam, xmlhttp, myObj, x = 0, objLen, txt = "";
obj = { table: "login", limit: 20 };
dbParam = JSON.stringify(obj);
xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
myObj = JSON.parse(this.responseText);
objLen = myObj.length;
txt += "<table border='1'>";
while (x < objLen) {
txt += "<tr>";
for (let [key, value] of Object.entries(myObj[x])) {
txt += "<td>" + value + "</td>";
}
txt += "</tr>";
x++;
}
txt += "</table>";
document.getElementById("myData").innerHTML = txt;
// console.log(JSON.parse(this.responseText));
}
};
xmlhttp.open("GET", "https://api.github.com/users", true);
xmlhttp.setRequestHeader("Content-type", "application//x-www-form-urlencoded");
xmlhttp.send("x="+dbParam);
<div id="myData"></div>
It shows all the fetched data in the table. One login in one column. You may change the HTML and manipulate as per your need.
Because the API is not returning any key named - name
Hit this URL on browser and see all the keys in response
https://api.github.com/users
I am changing key name to id, you may use any key which is being returned in response:
txt += "<table border='1'>"
for (x in myObj) {
txt += "<tr><td>" +myObj[x].id+ "</td></tr>";
}
txt += "</table>"

Fetching data from two API to merge them in one table

First of all,
you can see below, my working program to fetch Data from two different APIs in two different tables.
First table contains the data from an API : {Cycle, Delegated Stack, Share, expected payment}
The second one gets the data from another API to get : {the cycle, paid reward}
https://codepen.io/alexand92162579/pen/arJqmv?editors=1010
The second Code pen is the same thing but I want to merge the two tables according to the value of the cycle:
https://codepen.io/alexand92162579/pen/OGdjLJ?editors=1011
According to what I read online, I need to use Promises. I have tried this multiple times but never succeeded to make it work !
To try it, enter the Key KT19www5fiQNAiqTWrugTVLm9FB3th5DzH54 in the inputbox.
I will make a donation of 30xtz if someone helps me on this one.
// Fonction to fetch the data for every cycle on the first API
// Data Recolted (Cycle, Balance, Share, Expected Reward, Fee, Status)
// Try to merge with the second table according to the value of cycle
// // KT19www5fiQNAiqTWrugTVLm9FB3th5DzH54 */
function calculate2() {
var obj, dbParam, xmlhttp, myObj, x, txt = "";
obj = { table: "cycle", limit: 10 };
dbParam = JSON.stringify(obj);
xmlhttp = new XMLHttpRequest();
var KT1 = $('#KT1').val();
console.log(KT1);
xmlhttp.onreadystatechange = function() {
Qfee = 0.08;
if (this.readyState == 4 && this.status == 200) {
myObj = JSON.parse(this.responseText);
txt += "<table><tr bgcolor=#000000 color=White>"
txt += "<th>Cycle</th>"
txt += "<th>Balance</th>"
txt += "<th>Share</th>"
txt += "<th>Reward</th>"
txt += "<th>Fee</th>"
txt += "<th>Status</th>"
txt += "</tr>"
for (x in myObj) {
cycle = myObj[x].cycle;
balance = myObj[x].balance/1000000;
TotalReward = myObj[x].rewards/1000000;
status = myObj[x].status.status;
stakingBalance = myObj[x].staking_balance/1000000;
Share = balance/stakingBalance*100;
Fee = Share*TotalReward*Qfee/100;
DelegatorReward = Share*TotalReward/100 - Fee;
txt += "<tr>";
txt += "<td width=10% align=center>" + cycle + "</td>";
txt += "<td width=25% align=center>" + Math.round(balance*100)/100 + "</td>";
txt += "<td width=10% align=center>" + Math.round(Share*10)/10 + " %" + "</td>";
txt += "<td width=10% align=center>" + Math.round(DelegatorReward*100)/100 + "</td>";
txt += "<td width=10% align=center>" + Math.round(Qfee*1000)/10 + " %" + "</td>";
txt += "<td width=30% align=left>" + status + "</td>";
txt += "</tr>";
}
txt += "</table>";
document.getElementById("demo").innerHTML = txt;
}
};
xmlhttp.open("POST", "https://api6.tzscan.io/v3/delegator_rewards_with_details/" + KT1, true);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlhttp.send("x=" + dbParam);
}
/*Fonction to fetch the data for every cycle on the second API
// Data Recolted (Cycle, Payment)
// Try to merge with the first table according to the value of cycle
// // KT19www5fiQNAiqTWrugTVLm9FB3th5DzH54*/
function calculate3() {
var obj, dbParam, xmlhttp, myObj, x, txt = "";
obj = { table: "cycle", limit: 10 };
dbParam = JSON.stringify(obj);
xmlhttp = new XMLHttpRequest();
var KT1 = $('#KT1').val();
//console.log(KT1);
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
myObj = JSON.parse(this.responseText);
txt += "<table><tr bgcolor=#000000 color=White>"
//txt += "<th>Block</th>"
txt += "<th>Cycle</th>"
txt += "<th>Paid</th>"
txt += "</tr>"
//If one transaction has been done for the cycle get from the API request 1 then I put the data on the last column of the table
for (var x = 0; x < 30; x++) {
if (KT1 == myObj[x].type.operations[0].destination.tz) {
console.log("Get one");
Block = myObj[x].type.operations[0].op_level;
console.log(Block);
PaiementCycle = Math.round(Block/4096);
PaiementCycle = PaiementCycle - 6;
console.log(PaiementCycle);
Paid = myObj[x].type.operations[0].amount/1000000;
console.log(Paid);
txt += "<tr>";
//txt += "<td width=10% align=center>" + Block + "</td>";
txt += "<td width=10% align=center>" + PaiementCycle + "</td>";
txt += "<td width=25% align=center>" + Paid + "</td>";
txt += "</tr>";
console.log(txt);
} else {
//console.log("Next");
}
}
txt += "</table>";
document.getElementById("demo2").innerHTML = txt;
return txt;
console.log("ici :" + xmlhttp);
}
};
xmlhttp.open("POST", "https://api6.tzscan.io/v3/operations/tz1XynULiFpVVguYbYeopHTkLZFzapvhZQxs?type=Transaction&number=100", true);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlhttp.send("x=" + dbParam);
}
$(function () {
/*when #tezos input loses focus, as per original question*/
$('#KT1').blur(function () {
calculate3();
calculate2();
console.log(back)
});
$('#KT1').change(function () {
calculate3();
calculate2();
});
$('#KT1').on(function () {
calculate3();
calculate2();
});
$('#KT1').keyup(function () {
calculate3();
calculate2();
});
$('#KT1').keydown(function () {
calculate3();
calculate2();
});
});
</script>
not tested - but i think it might help - i also tried to reduce function sizes for readability ;)
function getAndLogKT1(){
var KT1 = document.querySelector('#KT1')
console.log(KT1 && KT1.textContent)
return KT1 && KT1.textContent
}
function firstApiReadystatechange(){
}
function createTable(){
return document.createElement('table');
}
function addTableHeader(table, keys){
var thead = document.createElement('thead');
var tr = document.createElement('tr');
for(var i = 0; i < keys.length; i++){
var th = document.createElement('th')
var text = document.createTextNode(keys[i])
th.appendChild(text)
tr.appendChild(th)
}
thead.appendChild(tr)
table.appendChild(thead)
}
function addRowToTableBody(table, rowItems){
var body = table.querySelector('tbody')
if(!body){
body = document.createElement('tbody')
table.appendChild(body)
}
var tr = document.createElement('tr')
for(var i = 0; i < rowItems.length; i++){
var td = document.createElement('td')
var text = document.createTextNode(rowItems[i])
td.appendChild(text)
tr.appendChild(td)
}
body.appendChild(tr)
}
function getDbParam(dbParmaObj){
return JSON.stringify(dbParmaObj)
}
function sendRequestFirstApi(xmlhttp, KT1, dbParam){
xmlhttp.open("POST", "https://api6.tzscan.io/v3/delegator_rewards_with_details/" + KT1, true);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlhttp.send("x=" + dbParam);
}
function fetchDataForEveryCycleOnFirstApi(){
return new Promise((resolve, reject) => {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function(){
var Qfee = 0.08;
if(this.readyState === 4 && this.status === 200){
try {
var responseObj = JSON.parse(this.responseText)
resolve(responseObj)
} catch {
reject({err: "json parse error"})
}
}
}
sendRequestFirstApi(xmlhttp, getAndLogKT1(), getDbParam({table: "cycle", limit: 10}))
})
}
function sendRequestSecondApi(xmlhttp, dbParam){
xmlhttp.open("POST", "https://api6.tzscan.io/v3/operations/tz1XynULiFpVVguYbYeopHTkLZFzapvhZQxs?type=Transaction&number=100", true);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlhttp.send("x=" + dbParam);
}
function fetchDataForEveryCycleOnSecondApi(){
return new Promise((resolve, reject) => {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function(){
var Qfee = 0.08;
if(this.readyState === 4 && this.status === 200){
try {
var responseObj = JSON.parse(this.responseText)
resolve(responseObj)
} catch {
reject({err: "json parse error"})
}
}
}
sendRequestSecondApi(xmlhttp, getDbParam({table: "cycle", limit: 10}))
})
}
function parseObjectCycleHashed(respObject){
var retObj = {}
for(var x in respObject){
retObj[respObject[x]['cycle']] = respObject[x]
}
return retObj
}
function mergeCycleHashedResponseObjects(a,b){
let cyclesA = Object.keys(a)
var retObj = Object.assign({}, b)
for(var i = 0; i < cyclesA.length; i++){
Object.assign(retObj, {[cyclesA[i]]: a[cyclesA[i]] })
}
return retObj
}
function addToDOM(element, querySelector){
var el = document.querySelector(querySelector)
el && el.appendChild(element)
}
async function main(){
var responseObjApiOne = await fetchDataForEveryCycleOnFirstApi();
var responseObjApiTwo = await fetchDataForEveryCycleOnSecondApi();
var responseObjApiOneCycleBased = parseObjectCycleHashed(responseObjApiOne);
var responseObjApiTowCycleBased = parseObjectCycleHashed(responseObjApiTwo);
var mergedObject = mergeCycleHashedResponseObjects(responseObjApiOneCycleBased, responseObjApiTowCycleBased)
var table = createTable()
const headerKeys = [
"Cycle",
"Balance",
"Share",
"Reward",
"Fee",
"Status",
"Paid"
]
addTableHeader(table, headerKeys)
for(var cycle in mergedObject){
addRowToTableBody(table, headerKeys.map(columnTitle => {
return mergedObject[cycle][columnTitle]
}))
}
addToDOM(table, "dmeo2")
}

how to display a resulted array from javascript on the html page

Continuing to develop my first web-service, faced a new problem...
I have a javascript function, which is provide a JSON object as array.
function RequestData(i){
var xhr = new XMLHttpRequest();
xhr.open('GET', '/getitemID='+i, true);
xhr.send();
xhr.onreadystatechange = function() { // (3)
if (xhr.readyState != 4) return;
if (xhr.status != 200) {
alert(xhr.status + ': ' + xhr.statusText);
} else {
alert(xhr.responseText);
var jsonData = JSON.parse(xhr.responseText);
for (var j=0; j< jsonData.length; j++ ){
alert(jsonData[j].name);
}
}
}
xhr.close();
}
there is an array with entities in jsonData like "name", "description", etc
The question is, how can i display a resulting JSON array on the html body of the page? like in foror foreach cycle
need just a simple example. imagine this how the JS file make the content of page
var contentString = '<div id="content">'+
'<div id="bodyContent">'+
'<button onclick="RequestData('+i+')">Load Data!</button>'+
'</div>'+
'</div>';
i want to insert a result from RequestData() function into the content of variable "var contentString"
You should probably use a callback here.
function RequestData(i, callback) {
var xhr = new XMLHttpRequest();
xhr.open('GET', '/getitemID='+i, true);
xhr.send();
xhr.onreadystatechange = function() { // (3)
if (xhr.readyState != 4) return;
if (xhr.status != 200) {
alert(xhr.status + ': ' + xhr.statusText);
} else {
// pass the parsed data as the parameter of the callback
callback(JSON.parse(xhr.responseText));
}
}
xhr.close();
}
// i is the id we're passing into the function
// and that is used in the xhr.open command
// this is an example
var i = 23;
// i gets passed in as the first parameter,
// the json gets passed as the second parameter to the callback
RequestData(i, function (json) {
// we create a little template using an array
var tmpl = [
'<div id="content"><div id="bodyContent">',
'<button onclick="RequestData(#name)">Load Data!</button></div></div>'
].join('');
var body = document.querySelector('body');
for (var i = 0, l = json.length; i < l; i++) {
// replace the name in the template with the json name for that index
var html = tmpl.replace('#name', json[i].name);
// use insertAdjacentHTML to add that HTML string to the body element
body.insertAdjacentHTML('afterbegin', html);
}
});
You can read more on the widely supported insertAdjacentHTML on the MDN page (it's the first I've heard of it!). And here's an example of it working.
for (var j=0; j< jsonData.length; j++ ){
GetHTML(j);
}
function GetHTML(j) {
var divwrapper = document.CreateElement('div');
var innerdivwrapper = document.CreateElement('div');
var textnode = document.createTextNode("my Name :" + j.Name + 'desc' + j.Description);
innerdivwrapper.appendChild(textnode);
divwrapper.appendChild(innerdivwrapper);
document.getElementsByTagName('body').appendChild(divwrapper);
}

Categories

Resources