My readyState in my onreadystatechange callback seems to be stuck at 1.
let req
function reloadData(){
let now = new Date()
url = 'liveData?' + now.getTime()
try {
req = new XMLHttpRequest()
} catch (e) {
try {
req = new ActiveXObject("Msxml2.XMLHTTP")
} catch (e) {
try {
req = new ActiveXObject("Microsoft.XMLHTTP")
} catch (oc) {
alert("No AJAX Support")
return
}
}
}
req.onreadystatechange = processData
req.open("GET", url, true)
req.send(null)
}
function processData(){
alert(req.readyState)
// If req shows "complete"
if (req.readyState == 4){
dataDiv = document.getElementById('currentData')
// If "OK"
if (req.status == 200)
{
// Set current data text
dataDiv.innerHTML = req.responseText
}
else
{
// Flag error
dataDiv.innerHTML = '<p>There was a problem retrieving data: ' + req.statusText + '</p>'
}
}
}
the request itself works and I log when /liveData gets a request and I get that log as well. I have no errors and the alert itself works so it is calling properly, but the readyState is at 1 at all times.
Turns out the server just wasn't sending a response, thank you Heretic Monkey for pointing that out in the comments.
Related
I'm trying to learn how to make an AJAX call using vanilla JavaScript in an effort to move away from JQuery for a little project that I'm working on but don't seem to be getting past xmlhttp.onreadystatechange. Can anyone point to what I'm doing wrong (the function getDVDsAndBluRays() is getting invoked on DOMContentLoaded)? Thanks!
function getDVDsAndBluRays() {
console.log("Getting logged");
var xmlhttp = new XMLHttpRequest();
var url = 'http://www.omdbapi.com/?t=metropolis&y=&plot=short&r=json';
xmlhttp.onreadystatechange = function() {
console.log("Not getting logged");
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
console.log('responseText:' + xmlhttp.responseText);
var myMovies = JSON.parse(xmlhttp.responseText);
myFunction(myMovies);
}
xmlhttp.open('GET', url, true);
xmlhttp.send();
};
}
function myFunction(myMovies) {
for (var i = 0; i < myMovies.length; i++) {
var title = myMovies[i].Title.toLowerCase().split(' ').join('+');
var year = myMovies[i].Year;
console.log(title + ", " + "year");
}
}
It should be like that, notice the location of open and send functions:
function getDVDsAndBluRays() {
console.log("Getting logged");
var xmlhttp = new XMLHttpRequest();
var url = 'http://www.omdbapi.com/?t=metropolis&y=&plot=short&r=json';
xmlhttp.open('GET', url, true);
xmlhttp.send();
xmlhttp.onreadystatechange = function() {
console.log("Not getting logged");
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
console.log('responseText:' + xmlhttp.responseText);
var myMovies = JSON.parse(xmlhttp.responseText);
myFunction(myMovies);
}
};
}
function myFunction(myMovies) {
for (var i = 0; i < myMovies.length; i++) {
var title = myMovies[i].Title.toLowerCase().split(' ').join('+');
var year = myMovies[i].Year;
console.log(title + ", " + "year");
}
}
onreadystatechange is executed after the call, you were actually "calling the service when it replies"
You have your .open() and .send() inside your onreadystatechange() handler. Put those outside of the onreadystatechange function and you should be good to go.
Onreadystatechange() is the event handler for when there is a change in state in the xmlhttp request, and will not get called until you open the request and send it.
Hope this helped!
You have put the calls to open and send inside the onreadystatechange event handler so they will never be called.
Move them outside it.
I'm making an http request asynchronously using XMLHttpRequest:
xhr.open(method, uri, true);
When I send something:
xhr.send(something)
When the server is down, it throws the following error:
net::ERR_CONNECTION_REFUSED
How can I catch and handle this error? The standard try..catch block doesn't work as the request is asynchronous.
Thanks in advance.
Use the onerror event of the XMLHttpRequest:
function aGet(url, cb) {
var x = new XMLHttpRequest();
x.onload = function(e) {
cb(x.responseText)
};
x.onerror= function(e) {
alert("Error fetching " + url);
};
x.open("GET", url, true);
x.send();
}
var dmp = console.log.bind(console); // Dummy callback to dump to console
aGet("/", dmp) // Ok, uses onload to trigger callback
aGet("http://dgfgdf.com/sdfsdf", dmp); // Fails, uses onerror to trigger alert
I wrote a full solution to that problem. It works perfectly!
I have a function called networkOrfail which will try to resend the XMLHttpRequest each second, if the network is available. Otherwise, it'll ignore the request.
When the request is succeeded, that polling stops and the response is returned.
Here's how to detect whether the network is available:
function getNavigatorConection() {
return navigator.onLine;
}
Then, create your XMLHttpRequest:
function makeRequest() {
let xhr = new XMLHttpRequest();
xhr.open('GET', 'anypage/anotherpage', true);
xhr.timeout = 2000;
xhr.onload = function () {
// Your request is completed
if (xhr.readyState == 4 && xhr.status == 200) {
// You're in a successfully condition
}
};
xhr.ontimeout = function (e) {
// Your request timed out
};
xhr.send(null);
}
Now, define your polling method as follows:
function networkOrFail(callFunc, callTime) {
let connected = getNavigatorConection();
let callableTimes = callTime < 2000 ? 2000 : callTime;
let toursBegin = 3;
let tours = toursBegin;
let intervalId;
let request = function() {
intervalId = setInterval(function() {
let connected = getNavigatorConection();
if (tours > 0) {
if (connected) {
callFunc();
tours =0;
return false;
}
tours--;
alert("i tryied againt to resend for another time and it remain just "+tours+" to retry");
} else {
clearRequest();
tours =toursBegin;
}
}, callableTimes > 5000 ? 5000 : callableTimes);
};
let clearRequest = function() {
clearInterval(intervalId);
intervalId = null;
};
if (connected)
callFunc();
else
request();
}
Finally, call the send method through the polling method by passing it toghether with the timeout in minutes:
networkOrFail(makeRequest, 5000);
I've looked at tons of demos and AJAX and JavaScript tutorials, but I can't seem to get this thing to work right. Here's what I've got...
function createRequestObject() {
var ro = false;
if (window.XMLHttpRequest) { // Mozilla, Safari, ...
ro = new XMLHttpRequest();
} else if (window.ActiveXObject) { // IE
try {
ro = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
ro = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) { }
}
}
return ro;
}
function ajaxrequest(){
var http = createRequestObject();
if(http) {
var name = "Strassburg";
var message = "Strike three you're out";
http.open('post', '/server/shout.php');
// needed in order for most servers to see POST data
http.setRequestHeader('Content-Type',
'application/x-www-form-urlencoded');
http.onreadystatechange = function() {
if(http.readyState == 4){
if(http.responseText.indexOf(':' != -1)) {
var data = http.responseText.split(':')
alert(data)
}
}
};
http.send('name=' + name + '&message=' + message);
}
}
Right now I'm doing it with static text (name and message instead of using the user entered fields), but I just get an empty alert. If the readyState is set to 4 this means that the ajax call was successful I believe? the server/shout.php was given to me, I dont understand php very well, but if a snippit of that is needed I can put it here as well.
its this line
http.responseText.indexOf(':' != -1)
( ":" != -1 ) = true, so indexOf is looking for true in the responseText
try this
http.responseText.indexOf(':') !== -1
readyState == 4 means that request was completed, to check if it was OK check http.status == 200
if (http.readyState == 4) {
if(http.status == 200) {
alert(http.responseText);
}
}
P.S. that should be a comment, but i don't have enough rating to comment your post
I have created XHR and I am also getting response from server correctly.
But for some reason the callback is not happening. Please help.
function uploadDr(){
var url = "UploadExcelServlet";
if (req != null) {
try {
req.open("GET", url, true);
} catch (e) {
alert(e);
}
req.onreadystatechange = callBk;
req.setRequestHeader("Content-Type", "multipart/form-data");
req.send();
} else {
alert("Null Request");
}
}
function callBk(){
if (req.readyState == 4){
if (req.status == 200){
alert(req.responseXml);
} else {
alert(req.statusText);
}
}
}
For GET requests you don't need set the "Content-Type" header, because the data are always passed in the URL.
And maybe you need set request data to send as follows:
req.send(null);
Then test readyState in callback function:
function callBk(){
console.log(req.readyState); // don't stop the script by using alert!
// other stuff
}
Make shure that readyState is not equal to 0 (XMLHttpRequest.UNSENT).
I have the below code:
sendRequest : function(data){
var me = this;
this._createData(data);
try{
this.req.open(this.method,this.page,true);
this.req.onreadystatechange=function()
{
if (this.readyState==4 && this.status==200)
{
if(this.responseText)
var response = eval('(' + this.responseText + ')');
else
response = null;
me.callBack(response);
return false;
}
}
this.req.send(this.data);
} catch(err){
me.callBack(response);
}
},
It works fine, and returns what I expect it to return, but when the connection is lost, it doesn't go into the catch block. What I want to know is how catch the request when server page is not available.
Here's an example from Microsoft's doc page for onreadystatechange:
function reportStatus()
{
if (oReq.readyState == 4 /* complete */) {
if (oReq.status == 200 || oReq.status == 304) {
alert('Transfer complete.');
}
else {
// error occurred
}
}
}
var oReq = new XMLHttpRequest();
oReq.open("GET", "http://localhost/test.xml", true);
oReq.onreadystatechange = reportStatus;
oReq.send();
Look where it says // error occurred.
There is a similar code example on this MDN documentation page.
I set a setTimeout before I send the Ajax call:
var timeout = window.setTimeout("functionToCallOnTimeout()", 2000);
inside functionToCallOnTimeout I stop the call:
oReq.current=null;
On a positive answer I clear the timeout:
timeout = null;