multiple XMLHttpRequests JavaScript - javascript

I have the following piece of code:
for(var i=0;i<searchParamLength;i++)
{
(function(i){
url = "https://www.googleapis.com/customsearch/v1?q=" + searchParam[i] + "&cx=005894674626506192190:j1zrf-as6vg&key=AIzaSyCanPMUPsyt3mXQd2GOhMZgD4l472jcDNM&dateRestrict=" + date_length;
arrXhr[i] = new XMLHttpRequest();
arrXhr[i].open("GET", url, true);
arrXhr[i].onreadystatechange = function(){
var totalResults = 0;
if (arrXhr[i].readyState === 4 && arrXhr[i].status == 200)
{
totalResults = JSON.parse(arrXhr[i].responseText).searchInformation.totalResults;
console.log("Variable I: " + i + "Total results:" + totalResults);
totalResultsArr.push(totalResults);
}
};
arrXhr[i].send(null);
})(i);
}
Take a look inside my loop where I have a console.log(). I was experiencing some strange behavior in my code which is why I decided to check if the loop is behaving as expected. Indeed, take a look at the image below. The loop is executing in a strange way. It is first executing i=1 and then i=6 and then i=2, etc.
I have been researching on SO and I saw the following question but it didn't help me solve my problem. Anyone has any clue why is this happening?

The requests are asynchronous. There's no guarantee that they will complete in the order you've made them in - that's why you're not seeing contiguous values for i in the callback.

JS moves on after sending the request and the onreadystatechange even occurs when you get a response. The time taken to receive response may vary by the status of the connection, server processing time, server load etc. So the order of response is not necessarily be the order of request.
You can make a synchronous call alternatively. This is decided by the third argument of xhr.open
arrXhr[i].open("GET", url, false);
The procedure is slightly different in this case.
Here is a tutorial.

Related

In a node.js API how do I perform tasks that must be synchronous without freezing the browser?

To start off this is what I am trying to accomplish:
I am trying to do file copies to an array of servers. There are several steps that must be completed in a specific order before and after these copies (for example, stopping IIS, backing up and clearing folders, running a bat file, etc) so they are not single operations.
To make this super easy I wrote an API in node.js that does simple tasks like copy files and folders, delete folders, etc. I then wrote a frontend in node.js using an express generator and Pug that uses javascript XMLHhttpRequests to send commands to the API depending on what I needed to do. I have the API written and running as well as the frontend. Now on to the problems:
If I have my XMLHttpRequest run in synchronous mode (example: xhttp.open("POST", url , false);) when the command is sent to the API to copy a folder if the folder takes several minutes to copy the browser freezes. Chrome displays a "Page Frozen" error. However, the job gets done correctly.
If I have my XMLHttpRequest run in asynchronous mode (example: xhttp.open("POST", url , true);) then every command gets sent to the API at once so that the fastest operation completes first and the commands are out of order. The copy will fail.
I've tried searching for a way to make it so that each operation sent from the frontend javascript has to return a SUCCESS (or 200 response) from the API before moving on to the next command but so far all I've seen is "just use synchronous". Right now that's what I'm doing. That doesn't seem like the best solution even though it works. Is there a better way to do this in a way that won't freeze the browser?
I figured this out by writing a function to handle the requests, setting a counter (for the steps of the process), and putting a switch statement in the if statement for the result. It wasn't exactly what I needed but the basics of my solution is in the answers to this question: How can I call ajax synchronously without my web page freezing
Here's what I did in case it helps anyone else who finds this question:
function myFunction (step, params, url) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
switch(step) {
case 2:
//url and params are set here, and step 2 is done here
myFunction(step, params, url);
break;
case 3:
// and so on and so forth
}
}
xhttp.open("POST", url , true);
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhttp.send(params);
step++;
}
//kick off the function
var step = 1;
var url = "my URL to the API with call";
var parameters = "my parameters";
myFunction(step, parameters, url);

Multiple xhr onload

I have this simple code for get elements from a external source
for(var i=0; i<10; i++)
loadPage(link[i]);
function loadPage(href)
{
var ajax = new XMLHttpRequest();
ajax.open('get',href);
ajax.responseType = 'document';
ajax.onreadystatechange=function()
{
console.log(ajax.responseXML.querySelectorAll("a[href^='magnet']")[0].getAttribute("href"));
}
ajax.send();
}
but when i read the console i get only 2 or 3 result instead of 10. i think is because i can't run multiple onload. How i can fix this?
By onload, you mean multiple ajax.send? that is likely not the problem.
Could is simply be that the returned ajax isn't returning something that matches your selector (magnet) or that your server doesn't answer properly to all requests? replace your console.log with a simple console.log ("Here be dragons");
If you ajax fetch pages from the same server, you should check the logs see how many requests do you have, and if you always reply correctly. Some servers will return at 50x error when too many requests in parallel, or put a breakpoint in your loadPage function, the pause is going to be enough to let the server process everything in time.

Making an ASP.NET MVC Ajax call with the use of Javascript

First off, thanks for taking the time to read.
I'm trying to delve into ASP.NET MVC at the moment, however i currently have no wish to use any type of JavaScript framework, so please, don't tell me how much easier it would be etc, in your answer.
I currently have a Javascript function that successfully makes an AJAX call, however i am struggling to understand why no values are being returned from the request.
The function is as follows.
function ajaxRequestUser(num) {
var ajax;
try {
ajax = new XMLHttpRequest();
} catch(e) {
try {
ajax = new ActiveXObject(Msxml2.XMLHTTP);
} catch(e){
alert('old browser');
}
}
ajax.readystatechange = function () {
if (ajax.readyState == 4) {
var queryResult = ajax.responseText;
if (!queryResult) {
alert('No Information.');
} else {
alert(queryResult);
}
}
}
var requestString = "?user="+num;
ajax.open("GET", "/Users/GetUser" + requestString, true);
ajax.send(null);
}
The function is called via a separate function that simply does some UI modifications to allow for the display of the data.
The alerts are there at this point, because i was not receiving any data back from the call and i was testing to see if that part of the code was being hit at all (Don't go into the differences between Synchronous and Asynchronous.). No matter how long i waited the data being returned was not being returned, after breaking through the actual server side c#, i saw the data being sent back, but it was just never being received. Is there something in the code that was done wrong? Or am i going about receiving the inbound data in the wrong way?
I have found the issue related to my code, and it is solely an error based around the declaration of my ajax.event where the event is onreadystatechange as opposed to readystatechange

Comet (long polling) and XmlHttpRequest status

I'm playing around a little bit with raw XmlHttpRequestObjects + Comet Long Polling. (Usually, I'd let GWT or another framework handle of this for me, but I want to learn more about it.)
I wrote the following code:
function longPoll() {
var xhr = createXHR(); // Creates an XmlHttpRequestObject
xhr.open('GET', 'LongPollServlet', true);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
...
}
if (xhr.status > 0) {
longPoll();
}
}
}
xhr.send(null);
}
...
<body onload="javascript:longPoll()">...
I wrapped the longPoll() call in an if statement that checks for status > 0, because I encountered, that when I leave the page (by browsing somewhere else, or by reloading it), one last unnecessary comet call is sent. [And on Firefox, it even causes severe problems when doing a page reload, for some reason I don't fully understand yet.]
Question: Is that status check the correct way to handle this problem, or is there a better solution?
My current answer - until proven false - is, that the solution is correct.
i like the simplicity of this loop.... i think the server side script has to sleep or atleast loop until it gets new data before its considered long polling though this is just normal polling. i would also add something to check if the reques fails though. wrapping that in a try catch bloch should do the trick

Problem with making a simple JS XmlHttpRequest call

Edit: Maybe I made the question more complex than it should. My questions is this: How do you make API calls to a server from JS.
I have to create a very simple client that makes GET and POST calls to our server and parses the returned XML. I am writing this in JavaScript, problem is I don't know how to program in JS (started to look into this just this morning)!
As n initial test, I am trying to ping to the Twitter API, here's the function that gets called when user enters the URL http://api.twitter.com/1/users/lookup.xml and hits the submit button:
function doRequest() {
var req_url, req_type, body;
req_url = document.getElementById('server_url').value;
req_type = document.getElementById('request_type').value;
alert("Connecting to url: " + req_url + " with HTTP method: " + req_type);
req = new XMLHttpRequest();
req.open(req_type, req_url, false, "username", "passwd");// synchronous conn
req.onreadystatechange=function() {
if (req.readyState == 4) {
alert(req.status);
}
}
req.send(null);
}
When I run this on FF, I get a
Access to restricted URI denied" code: "1012
error on Firebug. Stuff I googled suggested that this was a FF-specific problem so I switched to Chrome. Over there, the second alert comes up, but displays 0 as HTTP status code, which I found weird.
Can anyone spot what the problem is? People say this stuff is easier to use with JQuery but learning that on top of JS syntax is a bit too much now.
For security reasons, you cannot use AJAX to request a file from a different domain.
Since your Javascript isn't running on http://api.twitter.com, it cannot request files from http://api.twitter.com.
Instead, you can write server-side code on your domain to send you the file.

Categories