Overriding a variable within another function JS - javascript

Is it possible for me to call a function then override the contents of the variable before actually running it?
So I have a function that basically pulls in my Git profile like this:
var GetGitInfo = function() {
var xhr = new XMLHttpRequest();
var gitURL = "https://api.github.com/users/myself/repos";
xhr.open("GET", gitURL);
xhr.send(null);
xhr.onreadystatechange = function() {
var DONE = 4; // readyState 4 means the request is done.
var OK = 200; // status 200 is a successful return.
if (xhr.readyState === DONE) {
if (xhr.status === OK) {
// console.log(xhr.responseText);
console.log(JSON.parse(xhr.responseText));
} else {
console.log('Error: ' + xhr.status);
}
}
};
}
Then I call the function in another step by doing GetGitInfo(); which all works fine.
However, If I wanted to call the function and replace the gitURL variable how would I achieve that?
So something like
GetGitInfo(
gotURL= "https://api.github.com/users/new_user/repo";
);

You can't modify a local variable to a function from outside the function. They are private to the function's implementation.
But, since it's your own function, you can just create an argument that can be passed into the function. You can even make the argument optional so it will take your initial value as the default value if it is not passed.
var GetGitInfo = function(url) {
var xhr = new XMLHttpRequest();
var gitURL = url || "https://api.github.com/users/myself/repos";
xhr.open("GET", gitURL);
xhr.send(null);
xhr.onreadystatechange = function() {
var DONE = 4; // readyState 4 means the request is done.
var OK = 200; // status 200 is a successful return.
if (xhr.readyState === DONE) {
if (xhr.status === OK) {
// console.log(xhr.responseText);
console.log(JSON.parse(xhr.responseText));
} else {
console.log('Error: ' + xhr.status);
}
}
};
}
Then, you can use the function the way you were using it or you can pass in an URL to use:
getGitInfo(); // uses your default URL
getGitInfo("http://someURL"); // uses the URL you pass in
FYI, this function looks like it will ultimately need to either return a promise or accept a callback so you can communicate the results back to the caller.

From the snippet above you need to set the url as a function parameter so when calling it uses the specified url.
var GetInfo = function(url) {
var xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.send(null);
xhr.onreadystatechange = function() {
var DONE = 4; // readyState 4 means the request is done.
var OK = 200; // status 200 is a successful return.
if (xhr.readyState === DONE) {
if (xhr.status === OK) {
// console.log(xhr.responseText);
console.log(JSON.parse(xhr.responseText));
} else {
console.log('Error: ' + xhr.status);
}
}
};
GetInfo("https://api.github.com/users/myself/repos");

You should do a toString() on the function:
GetGitInfo.toString()
Then you should do a text search and replace on the variable and it's data:
GetGitInfo.toString().substring(0,GetGitInfo.indexOf('somestring'))+'gitUrl="newURL"'+GetGitInfo.toString().substring(.......)
Then you should eval that string!
Or, you know, use function parameters. Either way. Whatever's easiest.

Pass a parameter to the function:
var GetGitInfo = function(gitURL) {
var xhr = new XMLHttpRequest();
xhr.open("GET", gitURL);
xhr.send(null);
xhr.onreadystatechange = function() {
var DONE = 4; // readyState 4 means the request is done.
var OK = 200; // status 200 is a successful return.
if (xhr.readyState === DONE) {
if (xhr.status === OK) {
// console.log(xhr.responseText);
console.log(JSON.parse(xhr.responseText));
} else {
console.log('Error: ' + xhr.status);
}
}
};
}
GetGetInfo("https://api.github.com/users/myself/repos");

Just add a parameter to your function:
var GetGitInfo = function(gitURL) {
var xhr = new XMLHttpRequest();
xhr.open("GET", gitURL);
xhr.send(null);
xhr.onreadystatechange = function() {
var DONE = 4; // readyState 4 means the request is done.
var OK = 200; // status 200 is a successful return.
if (xhr.readyState === DONE) {
if (xhr.status === OK) {
// console.log(xhr.responseText);
console.log(JSON.parse(xhr.responseText));
} else {
console.log('Error: ' + xhr.status);
}
}
};
}
and call it like this:
GetGitInfo("https://api.github.com/users/myself/repos");

Use the parameters
var getData = function(url){
// url can be used here
}
var data = getData("http://apiurl.xy")

Related

What is the best way to do long polling in AJAX requests in JavaScript without JQuery?

hi after searching in the net about how to use the long polling in JavaScript I ended up with three ways, they are mentioned here briefly,but they are implemented using JQuery. I am confused which one to use in case that the AJAX request that I send to the server is asynchronous GET request ,and I don't know how many time it could take.
here is an example AJAX request:
function asynchGETRequest(method,url){
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
console.log("ok");
}
};
xhttp.open(method, url, true);
xhttp.send();
return (xhttp.responseText);
}
var clientFunctions={
getAnswers : function(callback){
var res=asynchGETRequest("GET", "http://localhost:9000/answers");
callback(JSON.stringify(res));
}
}
clientFunctions.getAnswers (function(){
//do some code here after the ajax request is ended
});
can some one guide me please?
I think I found the solution here
function loadFile(sUrl, timeout, callback){
var args = arguments.slice(3);
var xhr = new XMLHttpRequest();
xhr.ontimeout = function () {
console.error("The request for " + url + " timed out.");
};
xhr.onload = function() {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
callback.apply(xhr, args);
} else {
console.error(xhr.statusText);
}
}
};
xhr.open("GET", url, true);
xhr.timeout = timeout;
xhr.send(null);
}

Empty return value when parsing JSON using XMLHttpRequest

I have been trying to parse a bit of JSON from an API now and it was all working when I used
xmlHttp.open('GET', url, false);
But when I later wanted to expand my code using timeouts for the requests my function started to return empty values.
This is the function doing the actual parsing:
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState == 4) {
if (xmlHttp.status == 200) {
obj = JSON.parse(xmlHttp.responseText);
console.log(obj);
}
}
};
When I log the object returned here using console.log I get the JSON printed out to the console normally but later in my function I am returning the obj variable but it is always empty.
Here is the whole function:
static Parse(url: string): Object{
Asserts.isUrl(url, 'URL is invalid');
var obj = new Object();
var xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState == 4) {
if (xmlHttp.status == 200) {
obj = JSON.parse(xmlHttp.responseText);
//console.log(obj);
}
}
};
xmlHttp.open('GET', url, true);
xmlHttp.timeout = 2000;
xmlHttp.ontimeout = function () {
xmlHttp.abort();
throw new Error("Request Timed Out.");
};
xmlHttp.send();
return obj;
}
My first thought that it had something to do with the scope in Javascript but now after being stuck here for a few hours without progress I am clueless.
As I mentioned inside the xmlHttp.onreadystatechange = function () the console.log is actually logging the correct value. It's just that the obj variable created at the start of the function is not getting the value.
AJAX is asynchronous. This means that the onreadystatechange function will be called at a much later stage, probably after you have already returned from the Parse method. So you should not be trying to return obj from the Parse method. You would rather have the Parse method take an additional parameter that represents a callback function which you will invoke inside the onreadystatechange event and pass it the resulting object.
Here's what I mean:
static Parse(url: string, done: (obj: any) => void): void {
Asserts.isUrl(url, 'URL is invalid');
var xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState == 4) {
if (xmlHttp.status == 200) {
var obj = JSON.parse(xmlHttp.responseText);
// Pass the resulting object to the callback function
done(obj);
}
}
};
xmlHttp.open('GET', url, true);
xmlHttp.timeout = 2000;
xmlHttp.ontimeout = function () {
xmlHttp.abort();
throw new Error("Request Timed Out.");
};
xmlHttp.send();
}
and here's how you would call the Parse function:
Parse('http://foobar', function(obj) => {
// TODO: do something with obj here
console.log(obj);
});
So basically when you are writing a javascript application that uses asynchronous AJAX calls you should stop thinking in terms of sequential functions that you will invoke one after the other and which will return values. You should start thinking in terms of callbacks.
You need to pass a callback to the function:
static Parse(url: string, onSuccess: Function): Object{
Asserts.isUrl(url, 'URL is invalid');
var xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState == 4) {
if (xmlHttp.status == 200) {
var obj = new Object();
obj = JSON.parse(xmlHttp.responseText);
onSuccess(obj)
}
}
};
xmlHttp.open('GET', url, true);
xmlHttp.timeout = 2000;
xmlHttp.ontimeout = function () {
xmlHttp.abort();
throw new Error("Request Timed Out.");
};
xmlHttp.send();
}
and call the function with your callback parameter.

Ajax readyState returning always 0

I've got a problem with this Ajax code, is returning 0 everytime I access 'readyState'. Don't know what the source of the problem is yet, any help would be appreciated:
var xhr = null;
function performAjax(inputUrl){
// instantiate XMLHttpRequest object
try{
xhr = new XMLHttpRequest();
alert("XMLHttpRequest");
}
catch(e){
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
// handle old browsers
if( xhr == null ) {
alert("Ajax not supported by your browser");
return;
}
// get the URL
var url = inputUrl;
alert(inputUrl);
// get Ajax answer
xhr.onreadystatechange = handler();
//alert(xhr.readyState);
xhr.open("POST", url, true);
xhr.send(null);
}
function handler() {
alert("Handler: " + xhr.readyState + " Status: " + xhr.status);
// handle only loaded requests
if(xhr.readyState == 4) { // state 4: that data has been received
alert("here");
if(xhr.status == 200) {
alert(xhr.reponseText);
}
else alert("Error with Ajax");
}
}
You're assigning the handler function incorrectly:
xhr.onreadystatechange = handler; // <--- THERE SHOULD BE NO PARENTHESES
When you include the parentheses, you're asking that the function be called. Without them, you're merely referring to the function, which is what you want.

Ajax call issues more callbacks than expected

I have this code to make an ajax request, but according to Chrome Inspector the callback associated with the request is being called twice (by this I mean the response is being logged into the console twice), 2 more logs are being printed without any content. Here's the code:
var ajax = {
pull: function (settings) {
settings.type = 'get';
settings.callback = typeof (settings.callback) === 'function' ? settings.callback : false;
settings.data = settings.data ? settings.data : null;
return this.request(settings.url, settings.type, settings.callback, settings.data);
},
request: function (url, type, callback, data) {
var ids = ['MSXML2.XMLHTTP.3.0',
'MSXML2.XMLHTTP',
'Microsoft.XMLHTTP'],
xhr;
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
} else {
for (var i = 0; i < ids.length; i++) {
try {
xhr = new ActiveXObject(ids[i]);
break;
} catch (e) {}
}
}
if (callback) {
xhr.onreadystatechange = function () {
callback(xhr);
};
}
xhr.open(type, url, true);
if (type.toUpperCase() === 'GET') {
xhr.send();
} else if (type.toUpperCase() === 'POST') {
xhr.send(data);
}
}
}
ajax.pull({
url: 'http://localhost/my/twtools/scripts/ajax.php',
callback: function (xhr) {
console.log(xhr.response);
}
});
xhr.onreadystatechange has several steps (numbered from 0 top 4 I do believe something like 0 = uninitialized, 1 = starting etc, although I can't rember the exact names of the steps anymore, a quick google should find them), and each step is calling your callback. If I remember correctly, the last stage is 4, so I do believe you need to check something like this
if (xhr.readyState == 4 && xhr.status == 200)
{
// call has finished successfully
}
inside you callback, i.e. to check that it is all finished and got a successful response
I've been spoilt by jQuery these days (so much easier to do with jQuery), been quite a while since I wrote raw ajax
You're using onreadystatechange, which gets called more than once (once each state change).
Try using
xhr.onload = function() {
callback(xhr);
};

Unable to return an object's value from a JavaScript function

I have a function which attempts to capture a return value from a calling function in the following manner:
var select = xhrRetrieve(projID);
Here is an example of the xhrRetrieve function:
function xhrRetrieve(projID) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if(xhr.readyState == 4) {
if(xhr.status == 200) {
var obj = $.parseJSON(xhr.responseText);
return obj.select.toString();
}
}
}
var url = "ajax.cgi";
var data = "action=retrieve-opp&proj-id=" + projID;
xhr.open("POST",url);
xhr.setRequestHeader("Content-Type","application/x-www-urlencoded");
xhr.send(data);
}
I am using jQuery in conjunction with straight JavaScript. Whenever I attempt to get the value of obj.select using:
var select = xhrRetrieve(projID);
Select always comes back undefined.
What am I doing wrong?
The function doesn't return anything
The moment you call your function, the (not currently present) return value is being assigned to select. At the same moment, your ajax request is being fired, which takes time to complete; the callback function will not be called until the ajax request has completed (and succeeded).
This should work:
function doStuffWithTheAjaxResponse(select) {
// do stuff
}
function xhrRetrieve(projID) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if(xhr.readyState == 4) {
if(xhr.status == 200) {
var obj = $.parseJSON(xhr.responseText);
doStuffWithTheAjaxResponse(obj.select.toString());
}
}
}
var url = "ajax.cgi";
var data = "action=retrieve-opp&proj-id=" + projID;
xhr.open("POST",url);
xhr.setRequestHeader("Content-Type","application/x-www-urlencoded");
xhr.send(data);
}
Since the request is asynchronous the function will return before your code in onreadestatechange fires. You can switch to synchronous and get the value before the function returns:
function xhrRetrieve(projID) {
var returnVal;
var xhr = new XMLHttpRequest();
var url = "ajax.cgi";
var data = "action=retrieve-opp&proj-id=" + projID;
//3rd param is false to switch to synchronous
xhr.open("POST",url, false);
xhr.setRequestHeader("Content-Type","application/x-www-urlencoded");
xhr.send(data);
if(xhr.readyState == 4) {
if(xhr.status == 200) {
var obj = $.parseJSON(xhr.responseText);
return obj.select.toString();
}
}
}
The function xhrRetrieve doesn't have a return value. What do you expect to happen?
You have two functions there. The inner function returns a value, but not the outer one. The inner function is an event handler so the return value doesn't go anywhere. Your XMLHttpRequest is asynchronous, so you won't get a return value right away. See this post for a more detailed explanation: parameter "true" in xmlHttpRequest .open() method

Categories

Resources