JQUERY Ajax Get Method to get properties of data - javascript

I have this assignment of using JQUERY Ajax method in Javascript to get the data of the get request of a Gateway URL and send some of it's property values to the properties of an existing object. I believe there's a simple way to go about it. Below is code and i hope someone out there can help out.
<!DOCTYPE html>
<html>
<head>
<title>Gateway Object</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-
scale=1.0">
<script src="jquery-2.1.4.js"></script>
<script>
gateway = {
ip: "",
hwv: "",
setIpAddress: function (ip) {
var self = this;
self.ip = ip;
},
getHardwareVersion: function () {
var self = this;
$.ajax({
type: "GET",
url: "http://" + self.ip + "/command?XC_FNC=GetSI",
timeout: 2000,
error: function (err) {
console.log("gateway error: check ip address and
try again");
},
success: function (data) {
if (data) {
if (data.substr(0, 8) === "{XC_SUC}") {
var jString = (data.slice(8));
var obj;
try {
obj = JSON.parse(jString);
} catch (e) {
}
self.hwv = obj.HWV;
//console.log(self.hwv);
}
else {
console.log("Error:" + "" + data);
}
}
else {
console.log("error with the gateway");
}
}
});
}
};
gateway.setIpAddress("200.201.51.126");
gateway.getHardwareVersion();
console.log(gateway);
</script>
</head>
<body></body>
</html>
This seems to work fine but "gateway.hwv" can't receive the property of the data object after the ajax request. Is it possible to do this over Ajax-Asynchronous method?

Using console.log(gateway); directly after gateway.getHardwareVersion(); is not going to work as you're expecting as the log will run before your ajax query has finished processing.
You are going to either need to change your ajax function to by synchronous or run whatever logic you need to run after the ajax call from its success function.

You can add the complete function to the Ajax and call the console.log inside it. So it'll show the gateway object to you only when the async Ajax request completes.
A sample (I setted the self.hwv to 1 just to fill it):
<script>
gateway = {
ip: "",
hwv: "",
setIpAddress: function (ip) {
var self = this;
self.ip = ip;
},
getHardwareVersion: function () {
var self = this;
$.ajax({
type: "GET",
url: "http://" + self.ip + "/command?XC_FNC=GetSI",
timeout: 2000,
error: function (err) {
console.log("gateway error: check ip address and try again");
},
success: function (data) {
if (data) {
if (data.substr(0, 8) === "{XC_SUC}") {
var jString = (data.slice(8));
var obj;
try {
obj = JSON.parse(jString);
} catch (e) {
}
self.hwv = obj.HWV;
//console.log(self.hwv);
}
else {
console.log("Error:" + "" + data);
}
}
else {
console.log("error with the gateway");
}
},
complete: function() {
self.hwv = "1";
console.log(gateway);
}
});
}
};
gateway.setIpAddress("localhost");
gateway.getHardwareVersion();
</script>

Related

How to use defined variable out of function in javascript

I have a one signal javascript code and an ajax form, that give me a Player Id of the user in one signal,
so I want to use this code in my ajax login form and add the Player id to login form data, but i can't use a defined variable in one signal function, out of that and receive not defined message
OneSignal.push(function() {
OneSignal.getUserId(function(userId) {
var userid = userId;
});
});
var options = {
url: "{{CONFIG ajax_url}}/auth/login?hash_id=" + getHashID(),
beforeSubmit: function () {
$('#output-errors').empty();
$("#btn-submit").text("{{LANG Please wait..}}");
},
success: function (data) {
$("#btn-submit").text("{{LANG Login}}");
if (data.status == 200) {
if ($('#page').attr('data-page') != 'home' && $('#page').attr('data-page') != 'forgot' && $('#page').attr('data-page') != 'reset') {
$('#main-header').html(data.header);
$('#login_box').modal('hide');
if (Amplitude.getActiveSongMetadata().price >= 0) {
location.href = window.location.href;
} else {
ajaxRedirect();
}
} else {
location.href = window.location.href;
}
} else if (data.status == 400) {
var errros = data.errors.join("<br>");
$('#output-errors').html(errros);
}
},
// here i add the one signal id
data: {
OSid: userid
}
};
$('#login-form').ajaxForm(options);
There are a couple ways you can solve this, here's one approach:
OneSignal.push(function() {
OneSignal.getUserId(doAjax);
});
function doAjax(userId) {
var options = {
url: "{{CONFIG ajax_url}}/auth/login?hash_id=" + getHashID(),
beforeSubmit: function () {
$('#output-errors').empty()
...
}
$('#login-form').ajaxForm(options);
}
The function OneSignal.getUserId() takes a function as an argument, so my solution declares a function doAjax that will take the userId as an argument, and then we pass that function to the getUserId function.
Simplest way I suggest is:
Var userid;
OneSignal.push(function() {
OneSignal.getUserId(function(userId) {
userid = userId;
});
});

When submitting an ajax request, how can you "put the original request on hold" temporarily until a condition is met?

I am wanting to implement a recaptcha process that captures all ajax requests before they go through - the desired process would be as follows:
User completes an action which is going to cause an ajax request of some sort.
If the user has already completed the recaptcha process, the ajax request proceeds without further delay
If the user has not completed the recaptcha process, put the ajax request "on hold" temporarily until the recaptcha process is completed, then continue the ajax request.
I have got things to a state where I intercept the call, however I don't know how to put it on hold temporarily. Here's the relevant code:
<script>
var captchaValidated = null;
var currentRequests = [];
$.ajaxPrefilter(function (options, originalOptions, jqXHR) {
if (options.url != "/ValidateCaptcha") {
if (captchaValidated == null || captchaValidated == false) {
if (captchaValidated == null){
openRecaptcha();
} else {
verifyCaptcha(); //see async question in method
}
if (!captchaValidated) {
jqXHR.abort();
} else {
//let the original request proceed now - but how?!
}
}
}
});
function verifyCaptcha() {
var grecaptcha = $("g-recaptcha-response");
var encodedResponse;
if (grecaptcha != null) {
encodedResponse = grecaptcha.val();
$.ajax({
async: false, //set to false so that the calling method completes rather than async - what do you think?
headers: headers,
cache: false,
url: "/ValidateCaptcha",
type: 'POST',
contentType: 'application/json',
success: function (data) {
//parse the data - did we get back true?
captchaValidated = data;
},
error: function (raw, textStatus, errorThrown) { captchaValidated = null; alert("Validate ReCaptcha Error: " + JSON.stringify(raw)); },
data: JSON.stringify({ "encodedResponse": encodedResponse })
});
}
}
function invalidateCaptcha(){
captchaValidated = null;
}
function openRecaptcha() {
grecaptcha.render('recaptcha', {
'sitekey': "thekey",
'callback': verifyCaptcha,
'expired-callback': invalidateCaptcha,
'type': 'audio image'
});
$("#recaptchaModal").modal('show');
}
</script>
Any suggestions of how to proceed would be appreciated, thanks in advance!
Thank you #Loading and #guest271314 for your help in pointing me in the right direction that helped me get things figured out. I've pasted how I accomplished it below - perhaps it will be of help to someone else. Of course if anyone would like to weigh in on my implementation please do.
<script src="https://www.google.com/recaptcha/api.js?onload=onloadCaptcha&render=explicit&hl=en" async defer></script>
<script>
var captchaValidated = null;
var currentRequests = [];
var captchaPrompted = false;
var captchaReady = false;
var resetCaptcha = false;
function onloadCaptcha() {
captchaReady = true;
captcha = grecaptcha.render('recaptcha', {
'sitekey': '<yoursitekey>',
'callback': verifyCaptcha,
'expired-callback': invalidateCaptcha,
'type': 'audio image'
});
}
var deferredCaptcha = null;
var promiseCaptcha = null;
var captcha = null;
function openRecaptcha() {
if (!captchaReady) {
setTimeout(openRecaptcha, 50);
}
if (captchaPrompted) {
return;
}
captchaPrompted = true;
var captchaTimer = setInterval(function () {
if (captchaValidated != null) {
if (captchaValidated) {
deferredCaptcha.resolve();
} else {
deferredCaptcha.reject();
captchaValidated = null;
}
}
}, 100);
if (resetCaptcha) {
captcha.reset();
}
deferredCaptcha = $.Deferred();
promiseCaptcha = deferredCaptcha.promise();
promiseCaptcha.done(function () {
//captcha was successful
clearInterval(captchaTimer);
//process the queue if there's items to go through
if (currentRequests.length > 0) {
for (var i = 0; i < currentRequests.length; i++) {
//re-request the item
$.ajax(currentRequests[i]);
}
}
});
promiseCaptcha.fail(function () {
//captcha failed
clearInterval(captchaTimer);
currentRequests = []; //clear the queue
});
$("#recaptchaModal").modal('show');
}
function verifyCaptcha() {
resetCaptcha = true;
var response = $("#g-recaptcha-response").val();
var encodedResponse;
// confirm its validity at the server end
$.ajax({
headers: headers,
cache: false,
url: "/ValidateCaptcha",
type: 'POST',
contentType: 'application/json',
success: function (data) {
captchaValidated = data;
if (!data) {
captchaPrompted = false;
}
},
error: function (raw, textStatus, errorThrown) { captchaValidated = false; captchaPrompted = false; alert("WTF Validate ReCaptcha Error?!: " + JSON.stringify(raw)); },
data: JSON.stringify({ "encodedResponse": response })
});
}
function invalidateCaptcha(){
deferredCaptcha.reject();
captchaValidated = null;
resetCaptcha = true;
}
$.ajaxSetup({
beforeSend: function (xhr, settings) {
if (settings.url == '/ValidateCaptcha' || captchaValidated) {
// we're validating the captcha server side now or it's already been validated - let it through
} else {
if (typeof settings.nested === 'undefined'){
settings.nested = true; //this flag is to determine whether it's already in the queue
currentRequests.push(settings); //add the request to the queue to be resubmitted
//prompt them with the captcha
openRecaptcha();
}
return false; // cancel this request
}
}
});
</script>
At $.ajaxPrefilter() use .then() chained to openCaptcha to call verifyCaptcha
if (captchaValidated == null){
openRecaptcha().then(verifyCaptcha);
}
at verifyCaptcha use .is() with parameter "*" to check if an element exists in document
if (grecaptcha.is("*")) {
at openRecaptcha(), if grecaptcha.render does not return asynchronous result return jQuery promise object using .promise(); else chain to grecaptcha.render and $("#recaptchaModal").modal('show'); using $.when()
return $("#recaptchaModal").modal('show').promise()
or
return $.when(grecaptcha.render(/* parameters */)
, $("#recaptchaModal").modal('show').promise())
Something like this? (pseudo-code)
verified = false;
$('#myButton').click(function(){
if (!verified) verify_by_captcha();
if (verified){
$.ajax(function(){
type: 'post',
url: 'path/to/ajax.php',
data: your_data
})
.done(function(recd){
//ajax completed, do what you need to do next
alert(recd);
});
}
});//end myButton.click

How to Call a Web Service in a Cross-Browser way

I want to call a Web Service from Mozilla, Internet Explorer and Chrome.
Bellow is my LaboratoryService.js file which calls the Web Service:
function StringBuffer() {
this.__strings__ = new Array;
}
StringBuffer.prototype.append = function (str) {
this.__strings__.push(str);
};
StringBuffer.prototype.toString = function () {
return this.__strings__.join("");
};
function LaboratoryService() {
this.url = "http://25.48.190.93:8082/labratory?wsdl";
}
LaboratoryService.prototype.buildRequest = function () {
var oBuffer = new StringBuffer();
oBuffer.append("<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" ");
oBuffer.append("xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ");
oBuffer.append("xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">");
oBuffer.append("<soap:Body>");
oBuffer.append("<getLabratory xmlns=\"http://nano.ito.ir/\" />");
oBuffer.append("</soap:Body>");
oBuffer.append("</soap:Envelope>");
return oBuffer.toString();
};
LaboratoryService.prototype.send = function () {
var oRequest = new XMLHttpRequest;
oRequest.open("post", this.url, false);
oRequest.setRequestHeader("Content-Type", "text/xml");
oRequest.setRequestHeader("SOAPAction", this.action);
oRequest.send(this.buildRequest());
if (oRequest.status == 200) {
return this.handleResponse(oRequest.responseText);
} else {
throw new Error("Request did not complete, code " + oRequest.status);
}
};
LaboratoryService.prototype.handleResponse = function (sResponse) {
var start = sResponse.indexOf('div') - 4;
var end = sResponse.lastIndexOf('div') + 7;
return sResponse.substring(start, end);
};
Bellow is my HTML code which uses LaboratoryService.js to show data:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Get Labratories</title>
<script language="JavaScript" src="LaboratoryService.js"></script>
<script language="JavaScript" src="jquery-1.8.0.min.js"></script>
<script language="JavaScript" type="text/javascript">
$(document).ready(function () {
$("#btnGetLaboratories").click(function () {
var oService = new LaboratoryService();
var fResult = oService.send();
var newData = $('<div/>').html(fResult).text();
$("#divResult").html(newData);
});
});
</script>
</head>
<body>
<input id="btnGetLaboratories" type="button" value="Get Laboratories" />
<div id="divResult">
</div>
</body>
</html>
This approach works fine in Internet Explorer.
The problem is that this approach does not work in FireFox and Chrome.
I think that the oRequest.send(this.buildRequest()); does not work in FireFox and Chrome.
Edited Web Service Call Using JQuery
I changed LaboratoryService.prototype.send to use JQuery to call Web Service as bellow:
LaboratoryService.prototype.send = function () {
$.ajax({
type: "POST",
url: this.URL,
contentType: "text/xml",
headers: { "SOAPAction": this.action },
success: function (msg) {
return this.handleResponse(msg);
},
error: function (e) {
alert('error');
}
});
};
But it alerts error. How do I call Web Service using JQuery?
Again Edited Code
I changed my JQuery AJAX call as bellow. It works fine in Internet Explorer but returns error in Chrome and Firefox.
LaboratoryService.prototype.send = function () {
$.ajax({
type: "POST",
url: this.URL,
contentType: "text/xml; charset=\"utf-8\"",
dataType: "xml",
data: this.buildRequest(),
processData: false,
success: function processSuccess(data, status, req) {
if (status == "success") {
var sResponse = req.responseText;
var start = sResponse.indexOf('div') - 4;
var end = sResponse.lastIndexOf('div') + 7;
var newData = $('<div/>').html(sResponse.substring(start, end)).text();
$("#divResult").html(newData);
}
},
error: function () {
alert('error');
}
});
};
Just change :
LaboratoryService.prototype.send = function () {
var oRequest = new XMLHttpRequest;
oRequest.open("post", this.url, true);
oRequest.setRequestHeader('User-Agent','XMLHTTP/1.0');
oRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
oRequest.setRequestHeader("SOAPAction", this.action);
oRequest.send(this.buildRequest());
if (oRequest.status == 200) {
return this.handleResponse(oRequest.responseText);
} else {
throw new Error("Request did not complete, code " + oRequest.status);
}
};
Please, refer this link.

How could I trigger func when another has been completed?

I am using JQuery to collect latest tweets using Twitter API, but I am having some issues when calling two functions.
$(document).ready(function(){
JQTWEET.loadTweets();
});
This, is working ok, but then I want to call this function:
showHideTweets: function() {
alert("hola");
var ojeto = $(JQTWEET.appendTo).find(".item").first();
$(JQTWEET.appendTo).find(".item").first().css("display", "block");
},
Both functions are inside: jqtweet.js ...
loadTweets: function() {
var request;
// different JSON request {hash|user}
if (JQTWEET.search) {
request = {
q: JQTWEET.search,
count: JQTWEET.numTweets,
api: 'search_tweets'
}
} else {
request = {
q: JQTWEET.user,
count: JQTWEET.numTweets,
api: 'statuses_userTimeline'
}
}
$.ajax({
url: 'tweets.php',
type: 'POST',
dataType: 'json',
data: request,
success: function(data, textStatus, xhr) {
if (data.httpstatus == 200) {
if (JQTWEET.search) data = data.statuses;
var text, name, img;
try {
// append tweets into page
for (var i = 0; i < JQTWEET.numTweets; i++) {
img = '';
url = 'http://twitter.com/' + data[i].user.screen_name + '/status/' + data[i].id_str;
try {
if (data[i].entities['media']) {
img = '<img src="' + data[i].entities['media'][0].media_url + '" />';
}
} catch (e) {
//no media
}
var textoMostrar = JQTWEET.template.replace('{TEXT}', JQTWEET.ify.clean(data[i].text) ).replace('{USER}', data[i].user.screen_name).replace('{IMG}', img).replace('{URL}', url );
/*.replace('{AGO}', JQTWEET.timeAgo(data[i].created_at) ) */
//alert(JQTWEET.timeAgo(data[i].created_at));
$(JQTWEET.appendTo).append( JQTWEET.template.replace('{TEXT}', JQTWEET.ify.clean(data[i].text) )
.replace('{USER}', data[i].user.screen_name)
.replace('{NAME}', data[i].user.name)
.replace('{IMG}', img)
.replace('{PROFIMG}', data[i].user.profile_image_url)
/*.replace('{AGO}', JQTWEET.timeAgo(data[i].created_at) )*/
.replace('{URL}', url )
);
if ( (JQTWEET.numTweets - 1) == i) {
$(JQTWEET.appendTo).find(".item").last().addClass("last");
}
}
} catch (e) {
//item is less than item count
}
if (JQTWEET.useGridalicious) {
//run grid-a-licious
$(JQTWEET.appendTo).gridalicious({
gutter: 13,
width: 200,
animate: true
});
}
} else alert('no data returned');
}
});
callback();
},
showHideTweets: function() {
alert("hola");
var ojeto = $(JQTWEET.appendTo).find(".item").first();
$(JQTWEET.appendTo).find(".item").first().css("display", "block");
},
The problem is that if a call functions like this:
$(document).ready(function(){
JQTWEET.loadTweets();
JQTWEET.showHideTweets();
});
Second function executes before tweets has been loaded, so it have nothing to search in, because I can see the alert("hola") working, but Ojeto is 0.
I was trying to create some kind of callback inside loadTweets(); but I could not.
The callback isn't a bad idea.
change loadTweets to look like this:
loadTweets: function(callback) {
And call it here:
$.ajax({
...
success: function(data, textStatus, xhr) {
...
if (callback) callback();
}
});
And then in your DOM ready callback:
$(document).ready(function(){
JQTWEET.loadTweets(JQTWEET.showHideTweets);
});
Your other option (which I actually prefer, in general) is to use a deferred object:
loadTweets: function(callback) {
var def = $.Deferred();
...
$.ajax({
...
success: function(data, textStatus, xhr) {
...
def.resolve();
}
});
return def.promise();
}
...
$(document).ready(function(){
JQTWEET.loadTweets().done(JQTWEET.showHideTweets);
});
Try jQuery methods chaining:
$(document).ready(function(){
JQTWEET.loadTweets().showHideTweets();
});

Callback never called on Jquery.post();

I'm having some trouble using JQUERY Post function.
I have 2 functions that call JQUERY Post function.
Both of them is working fine, but the callback function is never called (handleLike).
When I call handleLike manually, it's works perfect.
(Even if handleLike has just an alert inside, the callback function is not called)
Could you please help me with this thing?
<script type="text/javascript">
$(document).ready(function() {
function handleLike(v_cb){
alert("Call back chamou!");
$('#erro').html(v_cb.mensagem);
if (v_cb.class == 'map'){
var elemento = $('#maplike');
}else{
var elemento = $('#commentlike'+v_cb.id);
}
if (!(elemento.hasClass('disabled'))){
elemento.addClass("disabled");
var likes = elemento.find('font').text();
likes++;
elemento.find('font').html(likes);
}
}
$('#maplike').click(function() {
//var map_id = $('#like').find('font').attr('value');
var id = $(this).attr("name");
if (!($(this).hasClass('disabled'))){
var JSONObject= {
"mensagem":"Testando Json",
"id":86,
"class":"map"
};
handleLike(JSONObject);
alert("Teste");
$.post(
'/cmap/maps/like',
{ id: id },
handleLike,
'json'
);
}
});
$('[id*="commentlike"]').click(function() {
//var map_id = $('#like').find('font').attr('value');
var id = $(this).attr("name");
if (!($(this).hasClass('disabled'))){
$.post(
'/cmap/comments/like',
{ id: id },
handleLike,
'json'
);
}
});
});
</script>
Diagnostic, not solution
Rationalizing and adding an error handler, you should get something like this :
$(document).ready(function() {
function handleLike(v_cb){
alert("Call back chamou!");
$('#erro').html(v_cb.mensagem);
var elemento = (v_cb.class && v_cb.class == 'map') ? $('#maplike') : $('#commentlike'+v_cb.id);
if (!elemento.hasClass('disabled')){
var f = elemento.addClass("disabled").find('font');
f.html(++Number(f.text()));
}
}
function ajaxError(jqXHR, textStatus, errorThrown) {
alert('$.post error: ' + textStatus + ' : ' + errorThrown);
};
$('#maplike').on('click', function() {
var $this = $(this);
if (!$this.hasClass('disabled')) {
$.post('/cmap/maps/like', { id: $this.attr("name") }, handleLike, 'json').fail(ajaxError);
}
});
$('[id*="commentlike"]').on('click', function() {
var $this = $(this);
if (!$this.hasClass('disabled')) {
$.post('/cmap/comments/like', { id: $this.attr("name") }, handleLike, 'json').fail(ajaxError);
}
});
});
untested
Barring mistakes, there's a good chance the error handler will inform you of what's going wrong.
I follow the Kevin B tip and use $ajax method.
It was a parseerror. Sorry.
The return of v_cb was not a json, it was a html. I correct my return, and everything was ok.

Categories

Resources