Use jQuery to replace XMLHttpRequest - javascript

I am quite new to JavaScript libraries. I wanted to replace my current code with jQuery. My current code looks like this:
var req;
function createRequest() {
var key = document.getElementById("key");
var keypressed = document.getElementById("keypressed");
keypressed.value = key.value;
var url = "/My_Servlet/response?key=" + escape(key.value);
if (window.XMLHttpRequest) {
req = new XMLHttpRequest();
} else if (window.ActiveXObject) {
req = new ActiveXObject("Microsoft.XMLHTTP");
}
req.open("Get", url, true);
req.onreadystatechange = callback;
req.send(null);
}
function callback() {
if (req.readyState == 4) {
if (req.status == 200) {
var decimal = document.getElementById('decimal');
decimal.value = req.responseText;
}
}
clear();
}
I wanted to replace my code with something a little friendlier like jQuery's
$.get(url, callback);
However it doesn't call my callback function.
Also I would like to call a function called createRequest continuously. Does jQuery have a nice way of doing that?
­­­­­­­­­­­­­­­­­­­­­­­

$.get(url, {}, callback);
should do the trick. Your callback could be simplified like this:
function callback(content){
$('#decimal').val(content);
}
Or even shorter:
$.get(url, {}, function(content){
$('#decimal').val(content);
});
And all in all I think this should work:
function createRequest() {
var keyValue = $('#key').val();
$('#keypressed').val(keyValue);
var url = "/My_Servlet/response";
$.get(url, {key: keyValue}, function(content){
$('#decimal').val(content);
});
}

Take out the readyState and status checks. jQuery only calls your callback upon success. Your callback is supplied the arguments (data, textStatus), so you should use data instead of req.responseText.
window.setTimeout() as suggested by another answer won't do what you want - that only waits and then calls your function once. You need to use window.setInterval() instead, which will call your function periodically until you cancel it.
So, in summary:
var interval = 500; /* Milliseconds between requests. */
window.setInterval(function() {
var val = $("#key").val();
$("#keypressed").val(val);
$.get("/My_Servlet/response", { "key": val }, function(data, textStatus) {
$("#decimal").val(data);
});
}), interval);

I don't think jQuery implements a timeout function, but plain old javascript does it rather nicely :)

According to the docs, jQuery.get's arguments are url, data, callback, not url, callback.
A call to JavaScript's setTimeout function at the end of your callback function should suffice to get this to continually execute.

There's no need to set the GET parameters on the URL, jQuery will set them automatically. Try this code:
var key = document.getElementById("key");
[...]
var url = "/My_Servlet/response";
$.get (url, {'key': key}, function (responseText)
{
var decimal = document.getElementById ('decimal');
decimal.value = responseText;
});

In the end I guess it was added the type. This seems to work for me.
function convertToDecimal(){
var key = document.getElementById("key");
var keypressed = document.getElementById("keypressed");
keypressed.value = key.value;
var url = "/My_Servlet/response?key="+ escape(key.value);
jQuery.get(url, {}, function(data){
callback(data);}
, "text" );
}
function callback(data){
var decimal = document.getElementById('decimal');
decimal.value = data;
clear();
}
Thanks Everyone for the help. I'll vote you up.

Related

AJAX call finishes after rest of the script

I Have an AJAX call to get entry's of a list from a database. So I recieve the Data from my Ajax call, but they are a little bit to "late" so the rest of the actions start before the neccessary data is fully loaded (see screenshot). Is there a way to pause the script until the ajax data is fully loaded to use all of the information? Does this happen because of the "asynchronus = true" ?
Would be nice to get some answers, Thanks!
Console shows this:
I tried to re-order the script, but nothing really changed the problem.
var data_array = [];
var data = [];
var output = document.getElementById('entry-list');
/*Static Data Variables for Data Call*/
var name;
var priority;
var category;
var expiry;
/*Call AJAX*/
var ajax = new XMLHttpRequest();
var method = "GET";
var url = "getdata.php";
var asynchronous = true;
ajax.onreadystatechange = function()
{
if (this.readyState == 4 && this.status == 200) {
/*getting return --> putting/convert json into array*/data.push(JSON.parse(this.responseText));
console.log(data.length);
for(var a = 0; a<data.length; a++){
name = data[a].name;
priority = data[a].priority;
category = data[a].category;
expiry = data[a].expiry;
data_array.push("<li class='' id='list-item"+a+"' onclick='itemClick(this)'>"+name+" #"+a+", "+priority+"</li>");
console.log("Array-entry added");
}
}
}
ajax.open(method, url, asynchronous);
//sending
ajax.send();
//recieving asnwer from getdata.php
console.log(data_array);
output.innerHTML = data_array;
Is there a way to pause the script
You're thinking about this the wrong way. Instead of trying to force operations to be blocking, instead re-structure your code to use the data in response to the asynchronous operation. Basically, the lines after //recieving asnwer from getdata.php should be in the callback function, not after it.
So instead of something like this:
ajax.onreadystatechange = function()
{
// the rest of your code
}
ajax.open(method, url, asynchronous);
ajax.send();
console.log(data_array);
output.innerHTML = data_array;
You would do something like this:
ajax.onreadystatechange = function()
{
// the rest of your code
console.log(data_array);
output.innerHTML = data_array;
}
ajax.open(method, url, asynchronous);
ajax.send();
Naturally, your code could get larger and more complex than just those two lines. How you structure the more complex operations is up to you. But the point is that those operations should be invoked by the response handler for the AJAX function.
You can do it this way with jquery AJAX.
$.ajax({
method:"POST",
url:"URL",
data: {name:value},
success: function (responseText) {
//CODE HERE RUN AFTER DATA FULLY LOADED
}
});

AJAX calls inside a loop

So, I have a list of data that I am out putting onto my view, and each list item has an id.
Each of these list items is a bar and I have a document created for each bar that at least one user is going to. For those bars where no users are going, there is no document created.
I need to make an AJAX call for each list item to the database to check
i) If a document exists for that list item
ii) If a document exists, how many users are going according to the document.
I attempted a solution using a while loop, where the update for the while loop was contained in the callback for the AJAX call. Here is the code
function updateAllGoingButtons(){
var i = 0;
var dataToPass = {};
var numButtons = global_data_object.listData.businesses.length;
while(i < numButtons){
dataToPass.button = global_data_object.listData.businesses[i].id;
dataToPass = JSON.stringify(dataToPass);
ajaxFunctions.ready(ajaxFunctions.ajaxRequest('POST', '/update-buttons', dataToPass, function(data){
console.log(i);
i++;
}));
}
}
When I attempted to run the function, I got the error,
Request entity too large
So, is there a better way to go about doing what I am trying to do? Should I use promises? Or is there simply an error in the way I am trying to make the AJAX call from within a while loop?
For reference, here is the ajaxRequest function
'use strict';
var appUrl = window.location.origin;
var ajaxFunctions = {
ready: function ready (fn) {
if (typeof fn !== 'function') {
return;
}
if (document.readyState === 'complete') {
return fn();
}
document.addEventListener('DOMContentLoaded', fn, false);
},
ajaxRequest: function ajaxRequest (method, url, data, callback) {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState === 4 && xmlhttp.status === 200) {
callback(xmlhttp.response);
}
};
xmlhttp.open(method, url, true);
xmlhttp.setRequestHeader('Content-type', 'application/json');
xmlhttp.send(data);
}
};
You should check out the npm library called async, it has an each method that you can do asynchronous calls within. If you use promises, the Promise.all method in Bluebird could be very useful for you.
So, here's how I did the multiple AJAX calls from within a loop. I used this resource https://medium.com/coding-design/writing-better-ajax-8ee4a7fb95f#.d7ymg99mp (Great resource!)
Here's the code
$('.btn-group').find('button').each(function() {
console.log($(this).attr('id'));
dataToPass.button = $(this).attr('id');
var ajax = $.ajax({
url: '/update-buttons',
method: 'post',
data: dataToPass,
dataType: 'json',
}).success(function(data){
console.log(data);
});
});
Essentially, what this does is selects a div with the class 'btn-group' and then iterates over each button within that div using the jQuery each operator. Then simply make an AJAX request and use the success chain callback to access the returned data.

XMLHttpRequest is not a function

I'm trying to write some client-side JavaScript using XMLHttpRequest:
$('#someId').on('input', function() {
var req = XMLHttpRequest();
// …
});
but I get the following error:
XMLHttpRequest is not a function. (In 'XMLHttpRequest()', 'XMLHttpRequest' is an instance of XMLHttpRequestConstructor)
How to fix this?
missed new, must be:
$('#someId').on('input', function() {
var req = new XMLHttpRequest();
// …
});
you can read more about XHRHttpRequest here -
https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest
and how to work with it here -
https://developer.mozilla.org/ru/docs/XMLHttpRequest
(only this page translation exists yet, but google translate can help a lot :) )
p.s. If you are using jQuery - better to use $.ajax() as #synthet1c said.
Read more about it here - http://api.jquery.com/jquery.ajax/
If you are already using jQuery, you can make ajax requests with $.ajax() method:
Example:
$('#someId').on('input', function() {
$.ajax({
url: 'some_file.php',
data: {
postparam_1: 'ok',
postparam_2: 'no'
},
method: 'get',
success: function(x) {
alert(x); // string result from server
},
error: function() {
alert('Error!');
}
});
});
If you want to use It in your app you have to retrieve XmlHttpRequest object that works across all browsers.
var XMLHttpFactories = [
function () {return new XMLHttpRequest()},
function () {return new ActiveXObject("Msxml2.XMLHTTP")},
function () {return new ActiveXObject("Msxml3.XMLHTTP")},
function () {return new ActiveXObject("Microsoft.XMLHTTP")}
];
function createXMLHTTPObject() {
var xmlhttp = false;
for (var i=0;i<XMLHttpFactories.length;i++) {
try {
xmlhttp = XMLHttpFactories[i]();
}
catch (e) {
continue;
}
break;
}
return xmlhttp;
}
XMLHttpRequest is a constructor and not a (usual) function in JavaScript and you need to use new XMLHttpRequest()
$('#someId').on('input', function() {
var req = new XMLHttpRequest();
// …
});
Refer this MDN article on using XMLHttpRequest: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest

Parsing arguments to functions involving ajax

I am having an issue trying to improve the functionality of my ajax functions by adding arguments to define what to do with the returned result.
So what i am trying to implement is a way to tell the function to append the result to a given element by its id. But i am having difficulty understanding how to add this functionality.
This is my current code:
var ajax = new function(){
var self = this;
self.x = function() {
if (typeof XMLHttpRequest !== 'undefined') {
return new XMLHttpRequest();
}
};
self.send = function(url, callback, method, data, sync) {
var x = self.x();
x.open(method, url, sync);
x.onreadystatechange = function() {
if (x.readyState == 4) {
callback(x.responseText)
}
};
if (method == 'POST') {
x.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
}
x.send(data)
};
self.get = function(url, data, callback, sync) {
var query = [];
for (var key in data) {
query.push(encodeURIComponent(key) + '=' + encodeURIComponent(data[key]));
}
self.send(url + (query.length ? '?' + query.join('&') : ''), callback, 'GET', null, sync)
};
};
I then make an ajax request like so:
//get the html file, and then call a function
ajax.get(dir.layout+'login.html',false,
function(){
elements.addTemplate(data,'parent',true);
});
In Chrome the xhr shows the correct data and contents, so i know that part works. In my elements.loadTemplate function i have these three lines with their actual values:
elements.addtemplate(data,div_id,append){
console.log(data); //shows:
console.log(div_id); //shows string: parent
console.log(append); //shows: true
}
Now the issue is data is blank, when i want it to contain the contents of the HTML file that I just requested (in this case login.html). I am wondering why it would show up as blank and how i can fix it?
your data is undefined because your callback doesn't accept a parameter
try this:
ajax.get(dir.layout+'login.html',false,
function(data){ // <=== data
elements.addTemplate(data,'parent',true);
});

Result of expression 'this.getURL'[undefined] is not a function

When i call a method directly without a setInterval the function works correctly
slider.prototype.onTouchEnd = function(e){
clearInterval(this.inter);
this.getURL(this.url + '/' + this.eid.id + '/' + this.currX);
e.preventDefault();
}
putting the same function in a setInterval give me following error:
Result of expression 'this.getURL'[undefined] is not a function
slider.prototype.onTouchStart = function(e){
e.preventDefault();
this.inter = setInterval("this.getURL('www.google.com')",100);
}
the code of getURL is:
slider.prototype.getURL = function(url){
console.log(url);
verzoek=new XMLHttpRequest();
verzoek.onreadystatechange=function(){
if(verzoek.readyState==4) {
if(verzoek.status==200) {
var data=verzoek.responseText;
}
}
}
verzoek.open("GET", url, true);
verzoek.send(null);
}
the this.inter is created in the constructor
var slider = function(eid){
...
this.inter = null;
}
I tried so many things but it keeps failing.
Thx in advance
You need to pass a real function to setInterval, you are currently passing a string.
If you change it to:
slider.prototype.onTouchStart = function(e){
e.preventDefault();
var that = this;
this.inter = setInterval(function(){that.getURL('www.google.com');},100);
}
Does it work?

Categories

Resources