Check if generated xml file exist with setInterval - javascript

I need to generate an XML file and than check if the file exist. The XML file is large and it takes time to create. So I thought I use an interval and check if the file exist.
But i get only an unlimited loop although the file was created or sometimes a 404 (theXmlfile.xml) in the browser console and everything stops.
var tid;
jQuery("#cxml").click(function(){
exeXml();
tid = setInterval(getAjax("theXmlfile.xml"),30000);
});
function exeXml(){ //The php file creates the XML file, this need some time
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", "CreateXML.php", true);
xmlhttp.send();
}
function getAjax(TheURL) {
jQuery.ajax({
url: TheURL,
type:'HEAD',
error: function() {
//error code
//alert("File not successfully created");
clearInterval(tid);
tid = setInterval(getAjax("theXmlfile.xml"),30000);
},
success: function(response) {
// exists code
clearInterval(tid);
alert("File successfully created");
}
});
}

setInterval takes a function as the first parameter, calling a function and passing a function is not the same thing.
tid = setInterval(function(){ // anonymous function passed to settimeout
getAjax("theXmlfile.xml");
},30000);
tid = setInterval(getAjax("theXmlfile.xml"),30000); // calling a function
in your code above you are actually passing the return of getAjax to setTimeout which is undefined since it doesn't return anything.
This also means that you're not actually waiting before checking if your file is generating.

Related

Passing/Accessing values from separate thread in javascript

I am trying to use following code which I had found/edited in another post.
I would like to use the function "IsValidImageUrl()" to instantly return result on the fly. Since this function runs in a separate thread, I had a trouble getting the value, for example, if I had "return True;" in place of "isValid=true;" I always get "undefined" in return. So I tried to use global variable "isValid", but it always seem to be one step behind, meaning I need to call the function twice, to get the result for the first call.
What am I fundamentally missing? or would you be able to suggest another method that I can do it?
Thank you!
<script>
var isValid;
function IsValidImageUrl(url) {
$("<img>", {
src: url,
error: function() { isValid=false; },
load: function() { isValid=true; }
});
}
IsValidImageUrl("https://www.google.com/logos/2012/hertz-2011-hp.gif");
alert(isValid);
IsValidImageUrl("http://google.com");
alert(isValid);
</script>
The problem is you have to wait for the image to either load or fail before you can use the status. The best way is to give the IsValidImgUrl function a callback function (or seperate ones for success and failure) to run when the image has loaded or an error has occured.
In this example the image element is also passed to the callback functions, so that they know which image they were called for.
function IsValidImageUrl(url, okFunc, errFunc)
{
var image = document.createElement("IMG");
image.src = url;
image.onload = function() {okFunc(image)};
image.onerror = function() {errFunc(image)};
}
function imageLoadSucces(image)
{
alert("image loaded: " + image.src);
}
function imageLoadFail(image)
{
alert("image load error: " + image.src);
}
IsValidImageUrl("https://www.google.com/logos/2012/hertz-2011-hp.gif", imageLoadSucces, imageLoadFail);
IsValidImageUrl("http://google.com", imageLoadSucces, imageLoadFail);

Chrome extension: Not downloading after clicking button

I'm trying to download a file to my downloads file. I'm creating a button on the web-page dynamically and id like to download something when that button is pressed. For what ever reason when I click the button nothing happens and I don't know why. Please help
background.js code
function SendRequest(url, callback){
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
callback(xhr.responseText);
}
};
xhr.open("GET", url, true);
xhr.send();
}
var objurl = localStorage.getItem("OBJURL");
function EditContent(objurl){
chrome.downloads.download({url:objurl,filename:"Object Edit - Chrome Extension.rbxl",conflictAction:"overwrite"})
}
item.js
contentInput.onclick = function(){
var assetid = $('.thumbnail-span').attr("data-3d-url")
var baseurl = 'http://www.roblox.com'
SendRequest(baseurl + assetid, function (response) {
var response = response; //Easy Peasy
var jsonObject = JSON.parse(response); //Parse the response
localStorage.setItem("URL1", jsonObject.Url); //It's saved!
var test = localStorage.getItem("URL1"); //Let's grab it and save it to a variable
console.log(test); //Logs "Hello World!"
});
var url1 = localStorage.getItem("URL1");
SendRequest(url1, function (response1) {
var response = response1; //Easy Peasy
var jsonObject = JSON.parse(response); //Parse the response
localStorage.setItem("OBJ", jsonObject.obj); //It's saved!
});
var hashdecode = "http://roblox.com/thumbnail/resolve-hash/"
var objhash = localStorage.getItem("OBJ");
SendRequest(hashdecode + objhash, function (objresponse) {
var response = objresponse; //Easy Peasy
var jsonObject = JSON.parse(response); //Parse the response
localStorage.setItem("OBJURL", jsonObject.Url); //It's saved!
});
chrome.extension.sendRequest({
action: "EditContent",
})
}
Oh boy. There's a lot wrong here. And I mean a lot.
chrome.extension.sendRequest is deprecated. Use chrome.runtime.sendMessage instead.
That said, you're sending the message, but nothing actually listens to it. action: "something" doesn't mean anything a priori, you need to react to that yourself:
// background.js
chrome.runtime.onMessage.addListener(
function(message, sender, sendResponse){
if(message.action == "EditContent") {
/* do stuff */
}
}
);
localStorage is NOT shared between the content script and the background script. In fact, background script has its own copy of localStorage (bound to chrome-extension://whateverisyourid/ domain) and the content script shares it with the page.
You should either use chrome.storage, which is shared but works differently, or pass what you need in the message, i.e. a message like:
{action: "EditContent", objurl: jsonObject.Url}
And use it:
chrome.runtime.onMessage.addListener(
function(message, sender, sendResponse){
if(message.action == "EditContent") {
EditContent(message.objurl)
}
}
);
A function defined in the background script (SendRequest) cannot be called in the content script. You need to move it to the content script, or call it from the background script.
Your SendRequest is asynchronous. If you write something like:
function f(){
action1();
SendRequest(url1, function(response){
action2();
});
action3();
SendRequest(url2, function(response){
action4();
});
action5();
}
f();
then this is what will happen:
action1()
SendRequest will queue a request with url1, but not wait for it
action3()
SendRequest will queue a request with url2, but not wait for it
action5()
Your function f() terminates, next in queue is the first request.
When the request finishes, action2() is run.
Next in queue is the second request.
When the request finishes, action4() is run.
This might even get swapped, I suppose, depending on which request finishes first.
You see the problem? You need to chain asynchronous calls instead:
function f(){
action1();
SendRequest(url1, function(response){
action2();
action3();
SendRequest(url2, function(response){
action4();
action5();
});
});
}
This might not be the full list of problems, and certainly is not a full working code.
Please, please debug your extensions next time. You can access errors from the content script in the page's console (Ctrl+Shift+J), and background page's console from chrome://extensions in Developer Mode.

JavaScript object construction and assignment not working

Can someone tell why my object img is not accepting its value outside the ajax call? I've also used a constructor function to create the object but that did not work as well. And the xml parsed values work, I've tested this. If i move the alert(img.location) inside the success event the correct value will show, but it will not outside the ajax function..
Help please...
function getImage(){
img = new Object();
$.ajax({
type: "GET",
url: "hvimage.xml",
dataType: "xml",
success: function(xmlData){
var randImageId = Math.floor(Math.random()*3);
$(xmlData).find("image").each(function(index, e){
if(index == randImageId){
img.id = $(this).attr("id");
img.location = $(this).find("location").text();
img.answer = $(this).find("answer").text();
}
});
},
error: function(xmdData){
alert("error");
}
});
alert("test");
alert(img.location); //Keep getting undefined here..
}
Thanks again,
Wenn
Because your AJAX request is asynchronous, so the code that comes after it does not wait for the response before it runs.
Any code that relies on the successful response needs to be placed in, or invoked from within the success: callback.
function getImage(){
img = new Object(); // 1. create object
// 2. send request
$.ajax({
type: "GET",
url: "hvimage.xml",
dataType: "xml",
success: function(xmlData){
// 4. response is received, and callback runs
var randImageId = Math.floor(Math.random()*3);
$(xmlData).find("image").each(function(index, e){
if(index == randImageId){
img.id = $(this).attr("id");
img.location = $(this).find("location").text();
img.answer = $(this).find("answer").text();
}
});
},
error: function(xmdData){
alert("error");
}
});
// 3. fire alerts
alert("test");
alert(img.location); //Keep getting undefined here..
}
The reason you've having problems is that the code doesn't run in the sequence it seems you think it will.
The success function runs when the async request returns, whereas the last two alerts are triggered immediately after the request is sent. The data you want to use in those last two alerts simply isn't available to the browser yet.

global variable won't update from function within AJAX success

OK, so I cannot seem to be able to change the global variable of systemPath after it goes through the ajax.It will work inside of ajax, but I need that updated variable outside of ajax. basically I'm trying to create an array of paths from xml and use them to locate other xml files that I can generate a table from.
Does anyone know what's going on here? Does ajax run before the variable is set and that is why I get an array length of 0 after the ajax?
var systemPath = new Array();
var techDigestArr = new Array();
var addToArray = function(thisarray, toPush){
thisarray.push(toPush);
}
$.ajax({
url: fullPath+"technical/systems/systems.xml",
dataType: ($.browser.msie) ? "text" : "xml",
success: function(data){
var xml;
if (typeof data == "string") {
xml = new ActiveXObject("Microsoft.XMLDOM");
xml.async = false;
xml.loadXML(data);
} else {
xml = data;
}
$(xml).find("system").each(function(){
var urlString = fullPath + "technical/system_" + $(this).attr("id") + "/" + $(this).attr("id") + "tech-digest.xml <br />";
//alert(urlString);
$("#td-articles").append(systemPath.length + urlString);
addToArray(systemPath,urlString);
//systemPath.push(urlString);
});
$("#msg-output").append("total - " +systemPath.length);//Returns 48
},//END SUCCSESS
error: function(){
alert("Sorry - ");
history.go(-1);
}
});//END AJAX CALL
$(document).ready(function(){
//$("#msg-output").append("total - " + systemPath.length); Returns 0
});
The ajax is ran asynchronously. Things execute in this order in your code.
stuff before $.ajax()
$.ajax() initiates an ajax call (while waiting for the response it continues to run the rest of the code)
stuff after $.ajax()
success callback
Note that depending on how fast the call is 3 and 4 might occur in reverse order (not the case here)
So when $(document).ready() is executed the ajax call might not have returned yet, so the code in the success callback didn't have a chance to execute. If you are lucky and have a fast connection than maybe the response will come before document ready, but it's unlikely.
Just so you can see that the global variable gets updated you can set a timeout:
$(document).ready(function(){
setTimeout(function(){
$("#msg-output").append("total - " + systemPath.length);
//if the delay set below is more than the time between the ajax request and the server response than this will print the correct value
},2000);
});

Change function on javascript prototype

I want to change the XMLHttpRequest send function so that a function is called before the request is made and after the request is complete. Here is what I have so far:
var oldSend = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.send = function() {
//this never gets called
oldOnReady = this.onreadystatechange;
this.onreadystatechange = function() {
oldOnReady();
ajaxStopped();
}
ajaxStarted();
// according to http://www.w3.org/TR/XMLHttpRequest/
// there's only ever 0 or 1 parameters passed into this method
if(arguments && arguments.length > 0) {
oldSend(arguments[0]); //gets to here, calls this method, then nothing happens
} else {
oldSend();
}
}
function ajaxStarted() {
ajaxCount++;
document.getElementById("buttonClicky").innerHTML = "Count: " + ajaxCount;
}
function ajaxStopped() {
$("#isRunning")[0].innerHTML = "stopped";
ajaxCount--;
document.getElementById("buttonClicky").innerHTML = "Count: " + ajaxCount;
}
However, I'm doing something wrong here because once it hits the oldSend() call, it never returns or triggers the onreadystatechange event. So I must be doing somethingclickCount wrong here. Any ideas? I set a breakpoint and it gets hit just fine when I call this:
$.ajax({
type: "GET",
url: "file.txt",
success: function(result) {
//this never gets called
document.getElementById("myDiv").innerHTML = result;
}
});
So my new function is getting called. I guess just don't know how to call the old function. Any ideas on how to fix this code so that the Ajax Request is actually made and my new callback gets called?
Note: I'm aware of the JQuery events that essentially do this. But I'm doing this so I can get it to work with any Ajax call (Mootools, GWT, etc). I am just happening to test it with Jquery.
You need to call old functions in the context of this.
E.g.: oldSend.call(this)

Categories