I have a function where the alert is working:
function RequestNext() {
var xhr = getXMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && (xhr.status == 200 || xhr.status == 0)) {
MyCard = GetCard(xhr.responseText);
**alert(MyCard.GetNo());**
return MyCard;
}
};
xhr.open("GET", "../../HttpRequest_Next.php" , true);
xhr.send(null);
}
Then I have this other function where the first one gets called and the same alert does not work:
function Start(){
var MyCard = RequestNext();
alert("Patience.js");
**alert(MyCard.GetNo());**
alert("test2");
//alert(Card.GetKind());
//WriteCard(Card);
alert("test3");
}
For information, those functions are in 2 files.
This is where a callback is a great idea. Basically you pass a function as an argument, so that you can then run that function when the ajax (which is asyncronous) completes. The syntax here may be slightly off, but you could do something like:
function RequestNext(callback) {
var xhr = getXMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && (xhr.status == 200 || xhr.status == 0)) {
MyCard = GetCard(xhr.responseText);
**alert(MyCard.GetNo());**
if (typeof callback=='undefined') return MyCard;
else {
return callback.call(MyCard);
}
}
};
xhr.open("GET", "../../HttpRequest_Next.php" , true);
xhr.send(null);
}
function Start(){
var MyCard = RequestNext(function() {
alert("Patience.js");
alert(this.GetNo());
alert("test2");
//alert(this.GetKind());
//WriteCard(this);
alert("test3");
return this;
});
}
Related
This is the current source code:
var xhttp = new XMLHttpRequest();
function passVars(var1, var2, var3) {
if (var1.readyState == 4) {
if (var1.status == 200) {
var data = var1.responseText;
if (data) {
playSuccess();
classSwitch(data, var2, var3);
} else {
playFailure();
alert("Error: returned status code " + var1.status + " " + var1.statusText);
}
}
}
}
xhttp.onreadystatechange = function() {
passVars(xhttp, "tab", "p1234");
};
xhttp.open("POST", "index.php", true);
xhttp.send(formData); //formdata is a POST send to PHP's backend which returns responseText = 0 or 1 for var data
function classSwitch(state, sOrigin, stateButtonID) {
if (sOrigin === "tab") {
Monitored = state;
if (state === "1") {
if (document.getElementById("setmonitoring").classList.contains("productmonitoringdisabled")) {
document.getElementById("setmonitoring").classList.remove("productmonitoringdisabled");
}
document.getElementById("setmonitoring").classList.add("productmonitoringenabled");
}
if (state === "0") {
if (document.getElementById("setmonitoring").classList.contains("productmonitoringenabled")) {
document.getElementById("setmonitoring").classList.remove("productmonitoringenabled");
}
document.getElementById("setmonitoring").classList.add("productmonitoringdisabled");
}
}
if (sOrigin === "issues") {
if (state === "1") {
if (document.getElementById(stateButtonID).classList.contains("productmonitoringdisabled")) {
document.getElementById(stateButtonID).classList.remove("productmonitoringdisabled");
} else document.getElementById(stateButtonID).classList.add("productmonitoringenabled");
}
if (state === "0") {
if (document.getElementById(stateButtonID).classList.contains("productmonitoringenabled")) {
document.getElementById(stateButtonID).classList.remove("productmonitoringenabled");
} else document.getElementById(stateButtonID).classList.add("productmonitoringdisabled");
}
}
}
Tried a lot of ways to pass them using mainly SO anwsers and each time var2 and var2 are undefined. This is used in an inventory control system, early alpha version. The idea is to pass element's id to change button class when the backend returns product's current monitoring state
Any ideas how to pass those variables? Thanks in advance
Your structure is no good. You can't pass xhttp like that in a asynchronous call. Rewrite it directly like this...
xhttp.onreadystatechange = function() {
if (xhttp.readyState == 4) {
if (xhttp.status == 200) {
var data = xhttp.responseText;
if (data) {
playSuccess();
classSwitch(data, 'tab', '1234');
} else {
playFailure();
alert("Error: returned status code " + xhttp.status + " " + xhttp.statusText);
}
}
}
};
Below is a minimal example of how to pass parameters to the onreadystatechange callback function. You've overcomplicated it a bit - there's no need to pass your xhttp variable to the callback either since it's already available in scope.
const xhr = new XMLHttpRequest();
xhr.open("GET", "https://developer.mozilla.org/");
xhr.send();
xhr.onreadystatechange = function() {
callback("tab", "1234");
};
function callback(var1, var2) {
console.log(`var1 = ${var1}`);
console.log(`var2 = ${var2}`);
//Do your xhr.readyState and xhr.status checks in this function
console.log(`xhr.readyState = ${xhr.readyState}`);
console.log(`xhr.status = ${xhr.status}`);
}
used
function passVars(var1, var2, var3) {
xhr.onreadystatechange = function(e) {}
}
the "e" in the function bracket will call back all var you have before in the function passVars
I tried to create AJAX function but it shows noting in output
var ajaxObj = function(url, meth, data = "") {
var x = new XMLHttpRequest();
x.onreadystatechange = function() {
if (x.readyState == 4 && x.status == 200) {
this.responseAjax = this.responseText;
}
}
x.open(meth, url, true);
x.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
x.send(data);
}
function showHint(str) {
var xhttp = new ajaxObj("gethint.php?q=" + str, "GET");
if (str.length == 0) {
document.getElementById("txtHint").innerHTML = "";
return;
}
document.getElementById("txtHint").innerHTML = xhttp.responseAjax;
}
<!DOCTYPE html>
<html>
<body>
<h3> Start typing a name in the input field below :</h3>
<form action="">
First Name : <input type="text" id="txt1" onkeyup="showHint(this.value)">
</form>
<p>Suggestions:
<sapn id="txtHint"></sapn>
</p>
</body>
</html>
I tried to get suggested Names from gethint.php file when user starts typing into text box.
But it seems that responseAjax gets value after showHint() call please help me.
You need to handle the AJAX request asynchronously. In your showHint function when you call
document.getElementById("txtHint").innerHTML = xhttp.responseAjax;
the AJAX call has not yet returned, so the xhttp.responseAjax object is not yet defined. You need to wait to handle the response once it arrives. You can pass a callback function in to the ajaxObj definition, and the object will call that function when it gets its response.
var ajaxObj = function(url, meth, callback, data = "") {
var x = new XMLHttpRequest();
x.onreadystatechange = function() {
if (x.readyState == 4 && x.status == 200) {
// we're ready to handle the response data now
callback(x.responseText);
}
}
x.open(meth, url, true);
x.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
x.send(data);
}
// Callback function to be invoked when AJAX is complete
function fillTxtHint(responseHtml)
{
document.getElementById("txtHint").innerHTML = responseHtml;
}
function showHint(str) {
if (str.length == 0) {
document.getElementById("txtHint").innerHTML = "";
}
// Pass in the callback function to be invoked when AJAX has returned
ajaxObj("gethint.php?q=" + str, "GET", fillTxtHint);
}
this inside onreadystatechange's handler is an instance of XMLHttpRequest so the line this.responseAjax = this.responseText is adding a field to the XMLHttpRequest object and setting its value to another field in the same object. This is completely redundant. In showHint, xhttp is an instance of ajaxObj and there is no responseAjax field ever defined for this object. You can directly set innerHTML of the element that shows suggestion inside the handler of onreadystatechange like the following:
function getSuggestions (meth, data) {
meth = meth.toUpperCase();
var params = "q=" + data;
var url = (meth == "GET") ? "gethint.php?" + params : "gethint.php";
var elem = document.getElementById("txtHint");
if (data.length == 0) {
elem.innerHTML = "";
return;
}
var x = new XMLHttpRequest();
x.onreadystatechange = function() {
if (x.readyState == 4 && x.status == 200) {
elem.innerHTML = this.responseText;
}
}
x.open(meth, url, true);
x.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
if (meth == "GET") {
x.send();
} else {
x.send(params);
}
}
and showHint becomes:
function showHint(str) {
getSuggestions ("GET", str);
}
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 am using vanilla javascript to making AJAX call to my APIs.
Below is my code which i am calling on click of a simple button:
getUserByUserId : function (callback){
var userid = localStorage.getItem('userid');
var userApiUrl = "http://174.129.30.174:8080/users/"+userid;
var xmlhttp = micropaywall.getAjaxInstance();
xmlhttp.onreadystatechange = function()
{
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var response = JSON.parse(xmlhttp.responseText);
callback(xmlhttp.responseText);
console.log(response);
console.log(xmlhttp.responseText);
}
};
xmlhttp.open("GET", userApiUrl, true);
xmlhttp.send(null);
}
But i get "callback is not a function" at line
callback(xmlhttp.responseText);
Below is my callback function :
getUserByUserIdCallback : function(response){
if(response != "")
{
var res = JSON.parse(response);
var arrAppid = res.appIds;
var userid = res._id;
localStorage.setItem('appid', arrAppid[0]);
var appid = localStorage.getItem('appid');
micropaywall.getUserAccountDetails(userid, appid);
}
}
Please correct me where I am making mistake.
If you don't need to change the "callback" function then you can just call it directly:
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var response = JSON.parse(xmlhttp.responseText);
getUserByUserIdCallback(xmlhttp.responseText);
console.log(response);
console.log(xmlhttp.responseText);
}
You would only need to pass in a callback function if you want different behavior when calling the getUserByUserId function.
In the change_text() function I am trying to pass it the xmhttp.responsetext variable.. but how will I do this? As I see no way yet on how to pass it?
<script type="text/javascript">
function ajax(url, func) {
this.url = url;
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if(xmlhttp.readyState == 2 && xmlhttp.status == 200) {
this.func = func;
}
}
xmlhttp.open();
xmlhttp.send()
}
function change_text() {
target = document.getElementById("x");
target.innerHTML = xmlhttp.responseText;
}
ajax("url.php", change_text);
</script>
Actually, to do this you don't want to use this at all, since you are not creating any instances of an object and it doesn't act like a constructor.
You can just:
function ajax(url, func) {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if(xmlhttp.readyState == 4 && xmlhttp.status == 200) {
// note: loaded is 4 ^
func(xmlhttp.responseText);
}
}
xmlhttp.open('GET', url, true);
// ^~~ you also forgot to pass parameters here
xmlhttp.send('');
}
That would make the ajax function work.
For your change_text function, it's not in the same function as ajax, so it does not have access to the xmlhttp variable. However, the ajax function passed the responseText to it, so just make your function receive it:
function change_text(responseText) {
var target = document.getElementById("x");
// ^~~ don't forget to declare local variables with `var`.
target.innerHTML = responseText;
}
For a working example, see the jsFiddle.
Change this.func = func; to this.func = function () { func(xmlhttp.responseText); };
<script type="text/javascript">
function ajax(url, func) {
this.url = url;
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if(xmlhttp.readyState == 2 && xmlhttp.status == 200) {
func(xmlhttp);
}
}
xmlhttp.open();
xmlhttp.send()
}
function change_text(xmlhttp) {
target = document.getElementById("x");
target.innerHTML = xmlhttp.responseText;
}
ajax("url.php", change_text);
</script>
You have to call your callback with parameters. Also note that this.url = url just sets window.url = url which is probably a bug.
You probably want xmlhttp.open("POST", url) instead.
Mike Samuel is almost correct, but change_text is missing an argument, try this:
<script type="text/javascript">
function ajax(url, func) {
this.url = url;
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
//did you mean: func(xmlhttp.responseText);
if(xmlhttp.readyState == 2 && xmlhttp.status == 200) {
this.func = function() {
func(xmlhttp.responseText);
};
}
}
xmlhttp.open();
xmlhttp.send()
}
function change_text(responseText) {
target = document.getElementById("x");
target.innerHTML = responseText;
}
ajax("url.php", change_text);
</script>