adding JSON in javascript with multiple urls - javascript

I need to parse through several JSON files, extract different values and then compare these values. I'm having trouble getting more than one JSON file to show up though...I think the"request.onload" only works once in the for-loop so maybe thats the reason.
var myArray = [7138, 6237];
for (i = 0; i < myArray.length; i++) {
//var id = 55;
var head = "https://developer.trimet.org/ws/V2/arrivals/locIDs/";
var tail = "/appID/30BE7218095886D573C04A41C/xml='true'";
var url = head + myArray[i] + tail;
//console.log(url);
var request = new XMLHttpRequest();
request.open('GET', url);
request.responseType = 'json';
request.send();
request.onload = function() {
var arrivalData = request.response;
console.log(arrivalData.resultSet);
}}
Explaination of the code: the array "myArray" contains two bus-stop IDs which are found with another piece of code (I am making small app to find the 10 closest bus stops and then tell the user how long before the next bus arrives at each bus stop. To test it out, I am just using two constant IDs). These IDs are plugged into a url that contains a JSON script detailing the bus schedule for that bus stop. I want to extract the JSON and save it as a separate JSON within the code. I think the current code does this now, but it only seems to work once. In the end, the for loop will add the arrival times to an array, these times will be compared to see which one comes sooner, then the soonest arrival time and its corresponding bus-stop ID will be found. Finally i want to make this a function that can take any array of bus-stop IDs so that I can find the soonest bus arrival time for any set of bus stops.If you want to look into the arrival times, you can go to the url link and see the JSON - the arrival times can be either "estimated" or "scheduled" and the values are in milliseconds since Jan 1 1970. If someone could help me just be able to access the JSONs outside of the request.onload function, i'd be very grateful.

XMLHttpRequest works in asynchronous manner. And for loop is synchronous. So your facing this problem. I think below piece of code solves your problem
var myArray = [7138, 6237];
myArray.forEach(function (id) {
//var id = 55;
var head = "https://developer.trimet.org/ws/V2/arrivals/locIDs/";
var tail = "/appID/30BE7218095886D573C04A41C/xml='true'";
var url = head + id + tail;
//console.log(url);
var request = new XMLHttpRequest();
request.open('GET', url);
request.responseType = 'json';
request.send();
request.onload = function() {
var arrivalData = request.response;
console.log(arrivalData.resultSet);
}
})

Adding as an answer too
var myArray = [7138, 6237];
//Define results globally
var results = [];
for (i = 0; i < myArray.length; i++) {
//var id = 55;
var head = "https://developer.trimet.org/ws/V2/arrivals/locIDs/";
var tail = "/appID/30BE7218095886D573C04A41C/xml='true'";
var url = head + myArray[i] + tail;
//console.log(url);
var request = new XMLHttpRequest();
//Move here so onload event is registered
request.onload = function() {
var arrivalData = request.response;
results.push(arrivalData.resultSet);
};
request.open('GET', url);
request.responseType = 'json';
request.send();
}
While this should work I think your problem could be solved with promises and it would make your code much more understandable.
Have a read on the promise api and especially Promise.All().
EDIT
Just a note on that requests array, since XMLHttpRequest and onload is asynchronous if you try to access the results array directly after running that for loop it will be empty. This is one of the reasons promises are so powerful.
Using the current method you won't have any way of knowing when both of the requests have finished unless you are constantly checking the length of the results array in a while loop or something, which would block the thread and make everything much worse.

Related

How to get "file" parameter of http request in javascript?

I'm trying to program a java script script that based on whether a user logs in properly or not will redirect them to a separate PHP script. The issue is that I can't seem to figure out how to get the file parameter of the request so that I can see if the request I'm looking for is there. How do I get the file parameter of a request in java script?
Sorry for misconceptions, what i mean by the file attribute is what is under the "file" section for each request in the following.
example
So if under the file tab of the packet, it set a certain file, how would i differentiate?
It's not clear what you're asking.
The part " so that I can see if the request I'm looking for is there" tells me, you want to debug your website, or at least, that's my interpretation of it.
If you use Chrome or Firefox Developer Edition, you can press F12 (or CTRL + SHIFT + J) to open the developer console.
Change to the tab "Network, and you'll see all the XMLHTTPRequests.
Click on a specific request, and you'll see its details.
A basic XmlHttpReuqest goes like this:
function reqListener () {
console.log(this.responseText);
}
var oReq = new XMLHttpRequest();
oReq.addEventListener("load", reqListener);
oReq.open("GET", "http://www.example.org/example.txt");
oReq.send();
And you get the result of your request in the callback function reqListener.
See also https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest
If you want to get the request handler's URL, that goes like this:
function reqListener (e) {
//console.log(this.responseText);
console.log(e);
console.log(e.currentTarget.responseURL);
}
var oReq = new XMLHttpRequest();
oReq.addEventListener("load", reqListener);
oReq.open("GET", "https://stackoverflow.com/questions/58407228");
oReq.send();
And if you want to get a parameter called "file" inside an url, this goes like
function getUrlVars(urlHref)
{
var vars = [], hash;
var hashes = urlHref.slice(urlHref.indexOf('?') + 1).split('&');
var i;
for (i = 0; i < hashes.length; i++)
{
hash = hashes[i].split('=');
vars.push(decodeURIComponent(hash[0]));
vars[decodeURIComponent(hash[0])] = decodeURIComponent(hash[1]);
} // Next i
return vars;
} // End Function getUrlVars
var dictParameters = getUrlVars("http://www.example.com/handler?file=bla.bin");
if (dictParameters.contains("file"))
{
console.log(dictParameters["file"]);
}
As for XMLHTTPRequest, it doesn't have a property called file.
Also, this is 2019, you should be using the FETCH-API with async and await, not the XMLHttpRequest-API, which doesn't use promises.
Here's a getting started overview.
Edit:
Ah, I see:
If you have a url, such as
var url = "http://www6.scratch99.com/web-development/javascript/test.js?abc=def";
you do
var url = "http://www6.scratch99.com";
var urlParts = url.replace('http://','').replace('https://','').split(/[/?#]/);
var domain = urlParts[0];
to get the domain part. Then you subtract the domain (+protocol), and end it at ? or #:
Full code:
var url = "http://www6.scratch99.com/web-development/javascript/test.js?abc=def";
// var url = "http://www6.scratch99.com";
// var url = "http://www6.scratch99.com?test=123";
var protocol = url.substr(0, url.indexOf(":") + 3)
var urlParts = url.substr(protocol.length).split(/[/?#]/);
var domain = urlParts[0];
var fileParts = url.substr(protocol.length + domain.length);
var file = fileParts.split(/[?#]/)[0];
and if you want the filename only:
var pathParts = file.split('/');
var fileOnly = pathParts[pathParts.length-1];

Accessing Elements and Attributes from a Live Feed XML

I am trying to access the time until the next bus arrives for a Live Feed bus transit system in Asheville NC at the given bus stop but I keep returning two console errors:
"time is not defined"
and
"Cannot read property of geElementsbyTagName of undefined"
You can use "470" as an exam stopID to see the XML file.
I have made sure the right stop ID is being added although I am not sure I am adding the ID correctly onto the URL.
If the element is nested in another, is that an issue?
var feedURL = "http://webservices.nextbus.com/service/publicXMLFeed?command=predictions&a=art&stopId="+stopID;
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function(){
if(this.readyState == 4 && this.status == 200){
attribute(this);
}
};
xhttp.open("GET", feedURL, true);
xhttp.send();
function attribute(feedURL){
var y;
var xmlDoc = xml.responseXML;
var time = "";
y = xmlDoc.getElementsbyTagName('prediction');
time = x.getAttribute('minutes');
}
console.log(time);
I am expecting the number of minutes given until the bus arrives at a given stop.
You are trying to log the value of variable time outside of the function you've defined it in. You could change your code to this and that should work:
function attribute(feedURL){
var y;
var xmlDoc = xml.responseXML;
var time = "";
y = xmlDoc.getElementsbyTagName('prediction');
time = x.getAttribute('minutes');
console.log(time);
}

Vanilla JavaScript async multiple xhr.open()

I would like know how to handle multiple xhr requests with vanilla JS. I want to open multiple html templates and load the page when all of them are ready. when I use few xhr.open() requests it will only return 1 template:
var xhr = new XMLHttpRequest();
xhr.onload = function() {
if(xhr.status === 200){
storage.append(xhr.responseText);
}
}
function getAsync(url) {
xhr.open('get', url);
xhr.send();
}
getAsync('localhost:3000/template1.html');
getAsync('localhost:3000/template2.html');
I understand that .open() only works 1 at a time.
So is it possible to load all teamplates asynchronously or should I just load one after another in a synchronous matter? Also, I wonder,if I should create multiple xhr = new XMLHttpRequest() objects so that I could run multiple .open()?
Thank you
You are using one variable to define the xhr request, and using that variable twice, thus overriding the variable the second time. You need to create a loop and use let xhr; instead of var xhr as let has a block scope, so each instance in the loop will be independently defined.
i.e. something like
// Create iterable list of URLS
let urls = ['localhost:3000/template1.html', 'localhost:3000/template2.html'];
// Loop through URLs and perform request
for(let i=0; i<urls.length; i++) {
let xhr = new XMLHttpRequest();
xhr.onload = function() {
if(xhr.status === 200){
storage.append(xhr.responseText);
}
}
xhr.open('get', urls[i]);
xhr.send();
}

How to display certain JSON elements in HTML?

I would like to display the variable "hashrate" from this JSON file on a HTML webpage. I have looked around the internet, but many of the methods have not worked. Sorry if this is a duplicate question, I am very lost.
var json = {"getpoolstatus":{"version":"1.0.0","runtime":19.948959350586,"data":{"pool_name":"Capy's Pool - Gabencoin","hashrate":5.8254222222222,"efficiency":0,"workers":0,"currentnetworkblock":21903,"nextnetworkblock":21904,"lastblock":21903,"networkdiff":0.0392466,"esttime":28935.733248,"estshares":2572,"timesincelast":189,"nethashrate":451133}}};
your variable - json.getpoolstatus.data.hashrate
var xhr = new XMLHttpRequest(); //Request the data
xhr.open('POST','http://gaben.capyspool.co.uk/gabencoin/public/index.php?page=api&action=getpoolstatus&api_key=72f3fd60d9a536215a6f6f92938592a60f919586635d7d0dedcf6a394888c435',true);
xhr.send();
xhr.onreadystatechange = function() {
if (this.readyState === 4) { //When it's ready
var data = JSON.parse(this.responseText); //Parse the data
alert(data.getpoolstatus.data.hashrate); //And here it is!
}
}

Browser crashes after 10-15 mins

In my app I'm displaying 10 charts (charts are from dygraphs.) to monitor data. For displaying charts I'm getting data from my sever by sending ajax request to 4 servlets on every 5 seconds. After 10-15 mins (don't know exact time.) my browser crashes saying "aw!! snap." What could be the reason? Is it javascript that is causing it? or is it because I'm sending request every 5 seconds?
Browser tested: Firefox and Chorme.
Note:- When I refresh the browser after crash it again works fine for 10-15 mins.
JS code:
var i=0;
var loc = new String();
var conn = new String();
var heapUsage = new String();
var cpuUsage = new String();
var thrdCnt = new String();
var heapUsageConsole = new String();
var cpuUsageConsole = new String();
var thrdCntConsole = new String();
var user = new String();
var MemTotal = new String();
function jubking(){
var xmlhttp;
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
} else {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
var url = "MonitorDBServlet";
xmlhttp.open("POST", url, false);
xmlhttp.send(null);
var str = xmlhttp.responseText;
var strArr = str.split(",");
url = "MonitorTomcatServlet";
xmlhttp.open("POST", url, false);
xmlhttp.send(null);
var appstr = xmlhttp.responseText;
var appArr = appstr.split(",");
url = "MonitorConsoleTomcatServlet";
xmlhttp.open("POST", url, false);
xmlhttp.send(null);
var appstrConsole = xmlhttp.responseText;
var appArrConsole = appstrConsole.split(",");
url = "CpuMemoryServlet";
xmlhttp.open("POST", url, false);
xmlhttp.send(null);
var statesStr = xmlhttp.responseText;
var states = statesStr.split(",");
if(i>30){
loc = loc.substring(loc.indexOf("\n")+1);
loc += i+","+strArr[0]+","+strArr[1]+"\n";
//--- Do same thing all other var
} else {
loc += i+","+strArr[0]+","+strArr[1]+"\n";
//--- Do same thing all other var
}
document.getElementById("dbSize").innerHTML = strArr[3];
document.getElementById("HeapMemoryUsageMax").innerHTML = appArr[1];
document.getElementById("HeapMemoryUsageMaxConsole").innerHTML = appArrConsole[1];
g = new Dygraph(document.getElementById("dbLocks"),
",locksheld,lockswait\n"+loc+"");
g = new Dygraph(document.getElementById("activeConnection"),
",Connections\n"+conn+"");
g = new Dygraph(document.getElementById("example2"),
",heapUsage\n"+heapUsage+"");
g = new Dygraph(document.getElementById("example3"),
",cpuUsage\n"+cpuUsage+"");
g = new Dygraph(document.getElementById("example4"),
",thread,peakThread\n"+thrdCnt+"");
g = new Dygraph(document.getElementById("example6"),
",heapUsage\n"+heapUsageConsole+"");
g = new Dygraph(document.getElementById("example7"),
",\n"+cpuUsageConsole+"");
g = new Dygraph(document.getElementById("example8"),
",thread,peakThread\n"+thrdCntConsole+"");
g = new Dygraph(document.getElementById("cpuStates"),
",user,system,nice,idle\n"+user+"");
g = new Dygraph(document.getElementById("memStates"),
",MT,MF,B,C,ST,SF\n"+MemTotal+"");
i = i + 1;
setTimeout("jubking()", 5000);
}
You can use about:crashes in FF to view the specific reason for your crash. As mentioned by others, you could be leaking memory if you're caching off data (assigning it to a variable) returned by your AJAX call and not clearing it when the next call is made.
Edit:
Just saw your comment - 1,923,481 K is definitely too much - you're leaking data somewhere. What OS are you running? If you run FF from console in *nix, you usually get some form of a dump into console when something's going wrong (not sure about Windows).
You could possibly try decreasing your poll intervals to once every few seconds and step through the script using Firebug or Chrome's debugger to see what's happening. Worst case, start commenting things out until you figure out exactly what is making your app crash. And then, figure out a way to fix it :)
I suspect that your dygraphs usage is, as you note in your comments, the source of your trouble. It looks like you're binding new graphs over and over again when you only want to update the data, using a moving window for the data would also help. Try reworking your updater to work like this pseudo-JavaScript:
var graphs = {
dbLocks: {
graph: new DyGraph(/* ... */),
data: [ ]
},
activeConnection: {
graph: new DyGraph(/* ... */),
data: [ ]
},
// etc.
};
var DATA_WINDOW_SIZE = 1000; // Or whatever works for you.
function update(which, new_data) {
var g = graphs[which];
g.data.push(new_data);
if(g.data.length > DATA_WINDOW_SIZE)
g.data.shift();
g.graph.updateOptions({ file: g.data });
}
function jubking() {
// Launch all your AJAX calls and bind a callback to each
// one. The success callback would call the update() function
// above to update the graph and manage the data window.
// Wait for all the above asynchronous AJAX calls to finish and
// then restart the timer for the next round.
setTimeout(jubking, 5000);
}
The basic idea is to use window on your data with a reasonable maximum width so that the data doesn't grow to chew up all your memory. As you add a new data point at the end of your data cache, you drop old ones off the other end once you hit your maximum comfortable size.
You can find some techniques for waiting for several asynchronous AJAX calls to finish over here: How to confirm when more than one AJAX call has completed? (disclosure: yes, that's one of my other answers).
The answer above advocates re-using your Dygraph object and calling g.updateOptions({file:...}) to reduce memory usage. This is a great way to do it.
The other way is to call g.destroy() before you redefine the Dygraph object. This will make dygraphs clear out all of its internal arrays and DOM references. Example:
g = new Dygraph(...);
g.destroy();
g = new Dygraph(...);
Read more here: http://blog.dygraphs.com/2012/01/preventing-dygraphs-memory-leaks.html

Categories

Resources