I am using JavaScript.
I amusing a setInterval timer method.
Inside that method I am changing the values of module variables.
The thing is in IE the changes to the variables are not 'saved'. But in Chrome they are.
What is the accepted practice to do what I need to do?
this is my code:
function start()
{
var myVar = setInterval(function () { GetTimings() }, 100);
}
var currentts1;
var currentts2;
var currentts3;
var currentts4;
var frameCounter;
function GetTimings() {
if (frameCounter < 1) {
frameCounter++;
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", urlTS, false);
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4) {
var nextts = xmlhttp.responseText;
var bits = nextts.split('|');
if (currentts1 != bits[0]) {
currentts1 = bits[0];
postMessage("0|" + bits[0]);
}
if (currentts2 != bits[1]) {
currentts2 = bits[1];
postMessage("1|" + bits[1]);
}
if (currentts3 != bits[2]) {
currentts3 = bits[2];
postMessage("2|" + bits[2]);
}
if (currentts4 != bits[3]) {
currentts4 = bits[3];
postMessage("3|" + bits[3]);
}
frameCounter--;
}
}
xmlhttp.send();
}
}
The variables:
currentts1
currentts2
currentts3
currentts4
frameCounter
values are not preserved...
Try this, but notice I changed the currentts* to an Array when you try to view them
function start() {
var myVar = setInterval(GetTimings, 100);
}
var currentts = [null, null, null, null];
var in_progress = 0; // clear name
function GetTimings() {
var xhr;
if (in_progress > 0) return; // die
++in_progress;
xhr = new XMLHttpRequest();
xhr.open('GET', urlTS);
function ready() {
var nextts = this.responseText,
bits = nextts.split('|'),
i;
for (i = 0; i < currentts.length; ++i)
if (currentts[i] !== bits[i])
currentts[i] = bits[i], postMessage(i + '|' + bits[i]);
--in_progress;
}
if ('onload' in xhr) // modern browser
xhr.addEventListener('load', ready);
else // ancient browser
xhr.onreadystatechange = function () {
if (this.readyState === 4 && xhr.status === 200)
ready.call(this);
};
// listen for error, too?
// begin request
xhr.send();
}
Related
I’ve got a call that brings up an url id for a recipe, that I’m trying feed into another call to return additional recipe data, but I think the scope is incorrect somewhere.
I’m getting
Cannot read property 'id' of undefined at XMLHttpRequest.http.onreadystatechange
in Chrome.
function searchFood() {
var http = new XMLHttpRequest();
var foodID = 'a1e1c125';
var foodApiKey = 'c84a720e4f1750b59ce036329fccdc00';
var foodMethod = 'GET';
var url = 'http://api.yummly.com/v1/api/recipes?_app_id=' + foodID + '&_app_key=' + foodApiKey + '&q=scandinavian';
http.open(foodMethod, url);
http.onreadystatechange = function() {
if (http.readyState == XMLHttpRequest.DONE && http.status === 200) {
var foodData = JSON.parse(http.responseText);
var foodName = foodData.matches[0].recipeName;
console.log(foodData);
for (var i = 0; foodData.matches.length; i++) {
var recipeId = foodData.matches[i].id;
console.log(recipeId);
}
function getRecipe() {
var http = new XMLHttpRequest();
var foodID = 'a1e1c125';
var foodApiKey = 'c84a720e4f1750b59ce036329fccdc00';
var foodMethod = 'GET';
var url = 'http://api.yummly.com/v1/api/recipe/' + recipeId + '?_app_id=' + foodID + '&_app_key=' + foodApiKey;
http.open(foodMethod, url);
http.onreadystatechange = function() {
if (http.readyState == XMLHttpRequest.DONE && http.status === 200) {
var data = JSON.parse(http.responseText);
console.log(data);
} else if (http.readyState === XMLHttpRequest.DONE) {
alert("something went wrong");
}
};
http.send();
};
} else if (http.readyState === XMLHttpRequest.DONE) {
alert('Something went wrong')
}
};
http.send();
};
Any tips would be appreciated, thanks
Your truthy check is always true
for (var i = 0; foodData.matches.length; i++)
you are missing i<
I have following code, which highlights (fadein/out) the replied comment (its a div element).
I show only 10 last comments on the page
If the comment is found, then I highlight it (working fine), otherwise I load all comments and then try to highlight necessary one. But after loadAllComments function in the else clause the hide() method is not working - I wonder why.
function showReply(reply){
var p = getElement(reply);
if (p) {
$("#" + reply).animate({
opacity: 0.5
}, 200, function () {
});
setTimeout(function () {
$("#" + reply).animate({
opacity: 1
}, 200, function () {
});
}, 1000);
}
else{
loadAllComments(); //load all elements. working fine
$("#"+reply).hide(); //nothing happens. :-(
}
function loadAllComments() {
deleteComments();
$('.show-more-button').hide();
var xhr = new XMLHttpRequest();
xhr.open('GET', api_url + 'video_comments/?video=' + video_id, true);
xhr.withCredentials = true;
xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
xhr.setRequestHeader("X-CSRFToken", $.cookie('csrftoken'));
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.status != 200) {
alert(xhr.responseText);
}
else {
var comments = JSON.parse(xhr.responseText);
for (var i = comments.results.length - 1 ; i >= 0 ; i--){
$('.comment-content-box').append(showComment(comments.results[i]));
}
}
}
};
xhr.send();
}
function deleteComments(){
var comments_count = $('.comment-content-box').children('div').length;
for (var i=0; i < comments_count; i++){
$('.comment-render-box').remove();
}
}
function showComment(comment) {
return "<div>" // example, there is plenty of code, but it's just a return function
}
You're performing an XHR which is asynchronous. Supply a callback function to loadAllComments to be executed after your XHR completes:
function loadAllComments(callback) {
deleteComments();
$('.show-more-button').hide();
var xhr = new XMLHttpRequest();
xhr.open('GET', api_url + 'video_comments/?video=' + video_id, true);
xhr.withCredentials = true;
xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
xhr.setRequestHeader("X-CSRFToken", $.cookie('csrftoken'));
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.status != 200) {
alert(xhr.responseText);
}
else {
var comments = JSON.parse(xhr.responseText);
for (var i = comments.results.length - 1 ; i >= 0 ; i--){
$('.comment-content-box').append(showComment(comments.results[i]));
}
// xhr is complete and comments are now in DOM
callback();
}
}
};
xhr.send();
}
...
// usage
loadAllComments(function() {
$('#' + reply).hide();
});
I'm trying to check many items against information on ajax URL. But when I'm running this function in browser, memory usage goes above 2 gigs and then browser crashes (Chrome, Firefox). What am I doing wrong? items variable is really big - >200 000 and also includes some large strings.
var items = [1,2,3,4,5,6,7,8,9,10,...,300000]
var activeItems = {}
function loopAjax(){
for (i=0; i < items.length; i++) {
var currItem = items[i];
var request = new XMLHttpRequest();
var found = 0
request.open("GET", "/item=" + currItem);
request.onreadystatechange = function() {
if (request.readyState == 4 && request.status == 200) {
var response = JSON.parse(request.responseText);
var active = response[0].active;
if (active) {
console.log("FOUND ACTIVE! " + currItem);
activeItems[found] = {"active": true, "item": currItem};
found++;
}
}
}
request.send();
}
}
Thank goodness the browser stalls and dies. If it didn't you just created a denial of service attack!
The problem needs to be reapproached. You better off creating a state machine which has a stack of requests in it. That way you only doing say 5 concurrent requests at a time.
function ItemChecker(sample_size, max_threads) {
this.sample_size = sample_size;
this.max_threads = max_threads;
this.counter = 0;
this.activeItems = [];
this.isRunning = false;
this.running_count = 0;
}
ItemChecker.prototype.start = function start() {
this.isRunning = true;
while (this.running_count < this.max_threads) {
this.next();
}
return this;
};
ItemChecker.prototype.stop = fucntion stop() {
this.isRunning = false;
return this;
};
ItemChecker.prototype.next = function next() {
var request, item_id, _this = this;
function xhrFinished(req) {
var response;
if (req.readyState !== 4) {
return;
}
_this.counter--;
if (req.status === 200) {
try {
response = JSON.parse(request.responseText);
if (response[0].active) {
_this.activeItems.push({
active: true,
item: item_id;
});
}
} catch(e) {
console.error(e);
}
// When finished call a callback
if (_this.onDone && _this.counter >= _this.sample_size) {
_this.onDone(_this.activeItems);
}
}
else {
console.warn("Server returned " + req.status);
}
}
if (!this.isRunning || this.counter >= this.sample_size) {
return;
}
item_id = this.counter;
this.counter++;
request = new XMLHttpRequest();
request.onreadystatechange = xhrFinished;
request.open("GET", "item=" + item_id);
request.send();
};
ItemChecker.prototype.whenDone = function whenDone(callback) {
this.onDone = callback;
return this;
};
This might work? Didn't try it for real. But you would call it with:
var item_checker = new ItemChecker(300000, 5);
item_checker.whenDone(function(active) {
// Do something with active
}).start();
function loadAll() {
var zip64;
var zipURL = 'settings/Images.zip';
var xhr = new XMLHttpRequest();
xhr.open('GET', zipURL, true);
xhr.responseType = 'arraybuffer';
xhr.onload = function() {
if (this.status == 200) {
var responseArray = new Uint8Array(this.response);
var d = responseArray.length;
var binaryString = new Array(d);
while (d--) {
binaryString[d] = String.fromCharCode(responseArray[d]);
}
var data = binaryString.join("");
zip64 = window.btoa(data);
zip.createReader(new zip.Data64URIReader(zip64), function(reader) {
reader.getEntries(function(entries) {
z = 0;
zloopid = setInterval(function() {
if (z >= entries.length || !entries[z]) {
clearInterval(zloopid);
reader.close();
start();
return;
}
if (entries[z].filename.split("/")[0] == "__MACOSX") {
z++;
return;
}
$("#loadimg").html("Loading " + entries[z].filename + ".... (" + (z + 1) + " of " + entries.length + ")");
var isMask = (entries[z].filename.replace(/^.*[\\\/]/, '') == "mask.jpg");
entries[z].getData(new zip.Data64URIWriter(), function(uri) {
if (isMask) {
imgtemp = new Image();
imgtemp.src = uri;
}
else {
var lol = new Image();
lol.src = uri;
imageLibrary.push(lol);
}
});
z++;
}, 0);
});
}, function(error) {
window.location = "error.html?err=Error by unzipper: " + error + " (Problem in Images.zip)";
});
}
else {
window.location = "error.html?err=Error while retrieving zip file (" + zipURL + ") : " + this.status;
}
};
xhr.send();
}
function start() {
var image = imgtemp;
width = image.width;
height = image.height;
So I have this piece of code. I have a global variable named imgtemp but everytime I set it in the if (inMask) block, it reverts to undefined when start() is called. Why is this?
loadAll() is called first, then start(). I can confirm that when the code that calls start() in loadAll() executes, imgtemp already turned back to undefined.
Thanks in advance!
It is because loadAll becomes async and returns before anything is loaded so when you call start the image has not been set yet. You'll need to "chain" them instead of calling them separately.
Only call loadAll() and then inside the loadAll add an event handler for loading the image which when loaded calls the start() function.
/* snip */
entries[z].getData(new zip.Data64URIWriter(), function(uri) {
if (isMask) {
imgtemp = new Image();
imgtemp.onload = function(event) {
start(); /* <--- HERE */
}
imgtemp.src = uri;
}
else {
/* snip */
What I'm trying to do is limit the options of one select box based on what the user chooses in a prior select box. It works perfectly in Chrome and Firefox, but in IE 10 the only thing that shows up is the text "Not Found". I'm not sure, but my guess is that something is going wrong in request.status. What it is, however, I have no idea.
function prepForms() {
for (var i = 0; i<document.forms.length; i++) {
var thisform = document.forms[i];
var departCity = document.getElementById("departcity");
departCity.onchange = function() {
var new_content = document.getElementById("ajaxArrive");
if (submitFormWithAjax(thisform, new_content)) return false;
return true;
}
}
}
function getHTTPObject() {
if (typeof XMLHttpRequest == "undefined")
XMLHttpRequest = function() {
try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); }
catch (e) {}
try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); }
catch (e) {}
try { return new ActiveXObject("Msxml2.XMLHTTP"); }
catch (e) {}
return false;
}
return new XMLHttpRequest();
}
function submitFormWithAjax(whichform, thetarget) {
var request = getHTTPObject();
if (!request) {return false;}
var dataParts = [];
var element;
for (var i = 0; i<whichform.elements.length; i++) {
element = whichform.elements[i];
dataParts[i] = element.name + "=" + encodeURIComponent(element.value);
}
var data = dataParts.join("&");
request.open("POST", "flightlocationfilter.asp#ajaxArrive", true);
request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
request.onreadystatechange = function() {
if (request.readyState == 4) {
if (request.status == 200 || request.status == 0) {
var matches = request.responseText.match(/<div id="ajaxArrive">([\s\S]+)<\/div>/);
if (matches.length > 0) {
thetarget.innerHTML = matches[1];
} else {
thetarget.innerHTML = "<p>--Error--</p>";
}
} else {
thetarget.innerHTML = "<p>" + request.statusText + "</p>";
}
}
};
request.send(data);
return true;
};
Edit: After walking through with the IE Developer Tools, it looks like the request.readyState is not moving beyond 1 to 4.