Json created to fit a structure - javascript

I have created a JSON like this one :
{"data":[{"content":"Event1","start":"new Date(2014,07,10)"},{"content":"Event2","start":"new Date(2014,07,17)"}],"success":true}
In order to fit the following code in Javascript :
data = [
{
'start': new Date(2010,7,23),
'content': 'Event'
},
{
'start': new Date(2010,7,23),
'content': 'Event'
},
];
Witth th JSON i have, i can easily access field, for example :
json.data[0].content
Return : "Event1"
My question is : how can i make the Javascript code "dynamic" to load every components in my JSON, assuming the fact that i don't know how many elements it will contains ?
Currently, i've done the followig code :
var xhr = new XMLHttpRequest();
xhr.open("GET", "/Test", true); // Call to a java servlet
xhr.send();
var json;
var jsonLength;
var data;
xhr.onreadystatechange = function(){
if(xhr.readyState == 4 && xhr.status == 200){
json = JSON.parse(xhr.responseText);
jsonLength = json.data.length;
}
}
data = [];
for(var i = 0 ; i < jsonLength ; i++){
data.push({
'start':json.data[i]['start'],
'content':json.data[i]['content']
})
}
timeline.draw(data);
EDIT : I don't even enter to the for loop ... Why ?

That's quite simple as these are just arrays and hash objects in JavaScript.
So you can just iterate over them:
for(var i = 0; i < json.data.length; i++) {
var item = data[i];
// Insert this into your data table
// Here you can use item which is set to the current item you are iterating over
}
JavaScript even let's you inspect your so you can look at the individual data item and find out what properties it has like this (see this question for details):
var keys = [];
for(var k in obj) keys.push(k);
UPDATE:
It seems you have fallen into the asynchrosity trap that JavaScript lays out.
The function xhr.onreadystatechange is only called once the event happens, the code below that function is executed instantly. So you where iterating over an empty dataset since the data you where looking at was not yet loaded.
JavaScript is very much callback based and especially with AJAX. Always keep in mind when the code will run, in this case xhr.onreadystatechange = function returns instantly and the code after continues to run. Only inside the function can you expect your variables to be set correctly.
var xhr = new XMLHttpRequest();
xhr.open("GET", "/Test", true); // Call to a java servlet
xhr.send();
var json;
var jsonLength;
var data;
xhr.onreadystatechange = function(){
if(xhr.readyState == 4 && xhr.status == 200){
json = JSON.parse(xhr.responseText);
jsonLength = json.data.length;
data = [];
for(var i = 0 ; i < jsonLength ; i++){
data.push({
'start':json.data[i]['start'],
'content':json.data[i]['content']
})
}
timeline.draw(data);
}
}

If your json is a string, just do
obj = JSON.parse(jsonString);
Then you'll have an object containing your json data, where you can access using obj[0].content (as an example)
Else, just iterate throught the json object, like Tigraine said.
(You question is a little bit unclear though)

try this:
var x={"data":[{"content":"Event1","start":"new Date(2014,07,10)"},{"content":"Event2","start":"new Date(2014,07,17)"}],"success":true};
for(i=0;i<x.data.length;i++)
{
console.log("content: "+x.data[i].content+" start: "+ x.data[i].start);
}

<script type="text/javascript">
var json = {
'data': [
{
'start': new Date(2010, 7, 23),
'content': 'Event'
},
{
'start': new Date(2010, 7, 23),
'content': 'Event'
},
]
};
alert(json['data'].length);
$(function() {
});
</script>

Related

Using a javascript array to request data from a JSON file

I was wondering if it's possible to request data from a JSON file (For example: customers.name). But instead of that using an array containing the JSON object names and looping it. My code is below.
function load(url ,callback) {
var xobj = new XMLHttpRequest();
xobj.overrideMimeType("application/json");
xobj.open('GET', url, true);
xobj.onreadystatechange = function () {
if (xobj.readyState == 4 && xobj.status == 200) {
callback(xobj.responseText);
}
};
xobj.send(null);
}
load("klanten.json", function(response) {
var klanten = JSON.parse(response);
//Array containing JSON file object names.
var infArray = ['name', "address", "email", "phone", "place", "zip"];
//Calling said info using a for loop.
for(var i = 0; i < infArray.length; i++) {
console.log(klanten[i].infArray[i]);
//It not working for some reason.
}
});
I`d love some help with this. And in case what im asking is completely stupid, also let me know! Any help is welcome, thanks!
Change console.log(klanten[i].infArray[i]); to:
console.log(klanten[i][infArray[i]]);

My jQuery Ajax Call to pure Javascript

I asked about 5 month ago about rewriting my ajax call in pure Javascript. Here the original post: https://stackoverflow.com/questions/35415812/need-help-to-rewrite-my-jquery-ajax-call-to-plain-javascript
I never thought about to rewrite the script completely because it works but now i need to rewrite the whole script to plain js. I already startet.
Here is the jQUery/JS mix:
var cc = document.getElementsByClassName("cart-count");
var wc = document.getElementsByClassName("wishlist-count");
var url = wp_ajax.ajax_url;
var data = {
action: 'get_counts'
};
// JQUERY JS mixed VERSION
$.ajax({
type: 'POST',
url: url,
data: data,
success: function (data) {
var counts = JSON.parse(data);
console.log(data);
for(var i = 0; i < cc.length; i++){
cc[i].innerText=counts["cartCount"];
}
for(var i = 0; i < wc.length; i++){
wc[i].innerText=counts["wlCount"];
}
}
});
console says:
{"cartCount":"(1)","wlCount":"(3)"}
That's right!
But now i tried to rewrite the rest. Here the latest:
var cc = document.getElementsByClassName("cart-count");
var wc = document.getElementsByClassName("wishlist-count");
var url = wp_ajax.ajax_url;
var data = {
action: 'get_counts'
};
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == XMLHttpRequest.DONE) {
if (xmlhttp.status == 200) {
//document.getElementById("myDiv").innerHTML = xmlhttp.responseText;
var counts = data
console.log(data);
for(var i = 0; i < cc.length; i++){
cc[i].innerText=counts["cartCount"];
}
for(var i = 0; i < wc.length; i++){
wc[i].innerText=counts["wlCount"];
}
console.log('done');
} else if (xmlhttp.status == 400) {
console.log('There was an error 400');
} else {
console.log('something else other than 200 was returned');
}
}
};
xmlhttp.open('POST', url, true);
xmlhttp.send(data);
It does't work. The console gives me not the value, just the var:
Object {action: "get_counts"}
My question/problem: How can i get the data action values without the jQuery ajax? Please no questions like "why not jQuery?".
Thanks for all help!!! Sorry for my english.
UPDATE:
I got it!
jQuery:
var data = {
action: 'get_counts'
};
JS:
url + '?action=get_counts'
add this
var data = JSON.parse(xmlhttp.responseText);//you have to parse result
before this
var counts = data
console.log(data);
You are not evaluating the AJAX response data, but the local variable data which is set above the AJAX call:
var data = {
action: 'get_counts'
};
You need to parse the AJAX response instead:
if (xmlhttp.status == 200) {
console.log( JSON.parse(xmlhttp.response) )
}
See: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/response
Its happening because Ajax is async request which the browser handers in a different thread than the one which is processing your code. Normally jquery and other similar frameworks have callback methods defined for that but in pure JS implementation you can use
xmlhttp.responseText
to fetch the output once the request is done

Parsing Json with Promise in Tableau

I'm working on tableau and I have to build my own web data connector.
I wrote it and it works perfectly on Chrome.
But when I use it into Tableau I get the foolowing error :
ReferenceError: Can't find variable: Promise file: http://localhost:9000/json-connector line: 246
My connector is devided in two parts. The first part call a web service to get a list of destinations and fill two lists with their names. The second part call another web service to get every paths beetween two selected destinations.
The error occured while I want to get the first list. I want to insist that it works on chrome, but not in tableau.
The portion of code where the error occured :
var getJSON = function(url) {
return new Promise(function(resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.open('get', url, true);
xhr.responseType = 'json';
xhr.onload = function() {
var status = xhr.status;
if (status == 200) {
resolve(xhr.response);
} else {
console.log("Something went wrong with the destination")
reject(status);
}
};
xhr.send();
});
};
I think that tableau doesn't support Promise. But I don't know how to make a work around. Thank's a lot for your help !
This is how I use this function :
getJSON('http://localhost:9000/stations').then(function(data) {
//alert('Your Json result is: ' + data.result); //you can comment this, i used it to debug
//result.innerText = JSON.stringify(data); //display the result in an HTML element
console.log("starting parsing on : " + data.length);
var listArrival = document.getElementById('Arrival'); //get the list where you want to add options
var listDeparture = document.getElementById('Departure');
if(listArrival == null || listDeparture == null) console.error("Impossible to retrieve the list")
var op;
var addedStations = [];
for(var i = 0; i < data.length ; i++){
var obj = data[i];
var overflowControler = 0;
for(var key in obj){
console.log(key + '=' + obj[key]);
if(key == 'name' && addedStations.indexOf(obj[key]) == -1){
op = new Option(obj[key], obj['nlc'], true);
op2 = new Option(obj[key], obj['nlc'], true);
if(op == null) console.error("Impossible to create the new option")
listArrival.add(op);
listDeparture.add(op2);
addedStations.push(obj[key]);
}
overflowControler ++;
if(overflowControler > maxLengthOfEachRecordFromJson) break; // overflow control
}
if(i > maxStationsRecordNumberFromJson) break; //overflow control
}
}, function(status) { //error detection....
alert('Something went wrong.');
});
As suggested by Tomalak I added a library to my script and Tableau is able to use Promise.
<script src="https://cdnjs.cloudflare.com/ajax/libs/es6-promise/3.2.1/es6-promise.min.js" type="text/javascript"></script>
I didn't make other changes in the code.

Javascript: XHR not handling multiple async requests

Hi I am trying to access one resource multiple times with with different parameters
In this case requesting
var domains = [
'host1',
'host2'
];
var requests = new Array();
for ( i in domains )
{
requests[i]=new request(domains[i]);
}
function request(site)
{
var url = 'get_remote_status.php?host='+site;
var queues = {};
http_request = new XMLHttpRequest();
http_request.open("GET", url, true, 'username', 'password');
http_request.onreadystatechange = function () {
var done = 4, ok = 200;
if (http_request.readyState == done && http_request.status == ok) {
queues = JSON.parse(http_request.responseText);
var queuesDiv = document.getElementById('queues');
print_queues(queues, queuesDiv, site);
}
};
http_request.send(null);
}
However, only one of of the requests is being handled by the code lambda. Chromium reports that both requests have been received and is viewable in the resourced pane.
Also if I make the request synchronous then it works fine. However this is not acceptable to the release code as a request may timeout.
Thanks
Define http_request using var. Currently, you're assigning the XHR object to a global variable. Because of this, your script can only handle one XHR at a time.
Relevant erroneous code:
function request(site)
{
var url = 'get_remote_status.php?host='+site;
var queues = {};
http_request = new XMLHttpRequest();
Proposed change:
function request(site)
{
var url = 'get_remote_status.php?host='+site;
var queues = {};
var http_request = new XMLHttpRequest(); //VAR VAR VAR !!!
When you omit var before a variable, the variable will be defined in the global (window) scope. If you use var before a variable, the variable is defined within the local scope (in function request, in this case).
In fact it is possible to run multiple async xhr call but you have to give them an unique id as parameter to be able to store and load them locally in your DOM.
For example, you'd like to loop on an array and make a ajax call for each object. It's a little bit tricky but this code works for me.
var xhrarray={};
for (var j=0; j<itemsvals.length; j++){
var labelval=itemsvals[j];
// call ajax list if present.
if(typeof labelval.mkdajaxlink != 'undefined'){
var divlabelvalue = '<div id="' + labelval.mkdid + '_' + item.mkdcck + '" class="mkditemvalue col-xs-12 ' + labelval.mkdclass + '"><div class="mkdlabel">' + labelval.mkdlabel + ' :</div><div id="'+ j +'_link_'+ labelval.mkdid +'" class="mkdvalue">'+labelval.mkdvalue+'</div></div>';
mkdwrapper.find('#' + item.mkdcck + ' .mkdinstadivbody').append(divlabelvalue);
xhrarray['xhr_'+item.mkdcck] = new XMLHttpRequest();
xhrarray['xhr_'+item.mkdcck].uniqueid=''+ j +'_link_'+ labelval.mkdid +'';
console.log(xhrarray['xhr_'+item.mkdcck].uniqueid);
xhrarray['xhr_'+item.mkdcck].open('POST', labelval.mkdajaxlink);
xhrarray['xhr_'+item.mkdcck].send();
console.log('data sent');
xhrarray['xhr_'+item.mkdcck].onreadystatechange=function() {
if (this.readyState == 4) {
console.log(''+this.uniqueid);
document.getElementById(''+this.uniqueid).innerHTML = this.responseText;
}
};
}
}
You have to set each xhr object in a global variable object and define a value xhrarray['xhr_'+item.mkdcck].uniqueid
to get its unique id and load its result where you want.
Hope that will help you in the future.

why i can't parse xml in javascript?

hello i have problem to parse xml..
i have xml like this :
<tejemahan>
<kategori> komputer </kategori>
<hasil> aplikasi komputer </hasil>
</terjemahan>
Edited:
xml above I get in that way :
var url="http://localhost:8080/inlinetrans/api/translate/"+userSelection+"/"+hasilStemSel+"/"+hasilStem;
var client = new XMLHttpRequest();
client.open("GET", url, false);
client.setRequestHeader("Content-Type", "text/plain");
client.send(null);
if(client.status == 200)
alert("the request success"+client.responseText);
else
alert("the request isn't success"+client.status+""+client.statusText)
}
and this is my code to parse an xml file above :
this.loadXML = function (){
var url = http://localhost:8080/coba/api/artikan/"+sel+"/"+hasilStemSel+"/"+hasilStem
xmlDoc=document.implementation.createDocument("","",null);
xmlDoc.load("url");
xmlDoc.onload= this.readXML;
}
this.readXML = function() {
alert(xmlDoc.documentElement.tagName);
alert(xmlDoc.documentElement.childNodes[0].tagName);
alert(xmlDoc.documentElement.childNodes[1].tagName);
alert(xmlDoc.documentElement.childNodes[0].textContent);
alert(xmlDoc.documentElement.childNodes[1].textContent);
}
i can execute this code
xmlDoc=document.implementation.createDocument("","",null);
xmlDoc.load("url");
but why i can't execute this code
xmlDoc.load = this.readXML ???
Try putting the onload handler assignment before the load() call. If you call load() first, the onload event will happen before you have assigned a handler to handle it. Like this:
xmlDoc=document.implementation.createDocument("","",null);
xmlDoc.onload= this.readXML;
xmlDoc.load("url");
Firstly, I second David Dorward's suggestion: use XMLHttpRequest instead, which will work in all major browsers. Code is below.
Secondly, your readXML function is flawed, since most browsers will include whitespace text nodes within the childNodes collection, so xmlDoc.documentElement.childNodes[0] will actually be a text node and have no tagName property. I would suggest using getElementsByTagName() or checking the nodeType property of each node as you iterate over childNodes.
Thirdly, your XML is not valid: the <tejemahan> and </terjemahan> do not match, although this may be a typo in your question.
var url = "http://localhost:8080/coba/api/artikan/"+sel+"/"+hasilStemSel+"/"+hasilStem;
var readXML = function(xmlDoc) {
alert(xmlDoc.documentElement.tagName);
var kategori = xmlDoc.getElementsByTagName("kategori")[0];
alert(kategori.tagName);
};
var createXmlHttpRequest = (function() {
var factories = [
function() { return new XMLHttpRequest(); },
function() { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); },
function() { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); },
function() { return new ActiveXObject("Microsoft.XMLHTTP"); }
];
for (var i = 0, len = factories.length; i < len; ++i) {
try {
if ( factories[i]() ) {
return factories[i];
}
}
catch (e) {}
}
})();
var xmlHttp = createXmlHttpRequest();
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
readXML(xmlHttp.responseXML);
}
};
xmlHttp.open("GET", url, true);
xmlHttp.send(null);

Categories