My jQuery Ajax Call to pure Javascript - javascript

I asked about 5 month ago about rewriting my ajax call in pure Javascript. Here the original post: https://stackoverflow.com/questions/35415812/need-help-to-rewrite-my-jquery-ajax-call-to-plain-javascript
I never thought about to rewrite the script completely because it works but now i need to rewrite the whole script to plain js. I already startet.
Here is the jQUery/JS mix:
var cc = document.getElementsByClassName("cart-count");
var wc = document.getElementsByClassName("wishlist-count");
var url = wp_ajax.ajax_url;
var data = {
action: 'get_counts'
};
// JQUERY JS mixed VERSION
$.ajax({
type: 'POST',
url: url,
data: data,
success: function (data) {
var counts = JSON.parse(data);
console.log(data);
for(var i = 0; i < cc.length; i++){
cc[i].innerText=counts["cartCount"];
}
for(var i = 0; i < wc.length; i++){
wc[i].innerText=counts["wlCount"];
}
}
});
console says:
{"cartCount":"(1)","wlCount":"(3)"}
That's right!
But now i tried to rewrite the rest. Here the latest:
var cc = document.getElementsByClassName("cart-count");
var wc = document.getElementsByClassName("wishlist-count");
var url = wp_ajax.ajax_url;
var data = {
action: 'get_counts'
};
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == XMLHttpRequest.DONE) {
if (xmlhttp.status == 200) {
//document.getElementById("myDiv").innerHTML = xmlhttp.responseText;
var counts = data
console.log(data);
for(var i = 0; i < cc.length; i++){
cc[i].innerText=counts["cartCount"];
}
for(var i = 0; i < wc.length; i++){
wc[i].innerText=counts["wlCount"];
}
console.log('done');
} else if (xmlhttp.status == 400) {
console.log('There was an error 400');
} else {
console.log('something else other than 200 was returned');
}
}
};
xmlhttp.open('POST', url, true);
xmlhttp.send(data);
It does't work. The console gives me not the value, just the var:
Object {action: "get_counts"}
My question/problem: How can i get the data action values without the jQuery ajax? Please no questions like "why not jQuery?".
Thanks for all help!!! Sorry for my english.
UPDATE:
I got it!
jQuery:
var data = {
action: 'get_counts'
};
JS:
url + '?action=get_counts'

add this
var data = JSON.parse(xmlhttp.responseText);//you have to parse result
before this
var counts = data
console.log(data);

You are not evaluating the AJAX response data, but the local variable data which is set above the AJAX call:
var data = {
action: 'get_counts'
};
You need to parse the AJAX response instead:
if (xmlhttp.status == 200) {
console.log( JSON.parse(xmlhttp.response) )
}
See: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/response

Its happening because Ajax is async request which the browser handers in a different thread than the one which is processing your code. Normally jquery and other similar frameworks have callback methods defined for that but in pure JS implementation you can use
xmlhttp.responseText
to fetch the output once the request is done

Related

Asynchronous Ajax Call Mixing Up Callbacks

So basically I have an ajax function pretty standard one. Like so:
function ajax_call(rest_req, url, success_callback, fail_callback) {
// if (request_in_progress)
// return;
// request_in_progress = true;
var xhttp = new XMLHttpRequest;
xhttp.onreadystatechange = function () {
if (this.readyState == 4) {
// request_in_progress = false;
if (this.status == 200) {
success_callback(this);
}
else {
fail_callback(this);
}
}
};
xhttp.open(rest_req, url, true);
xhttp.send();
}
When I use the ajax function this way:
(function() {
function setup() {
ajax_call("GET", "url1", function(xhttp) {
response = JSON.parse(xhttp.responseText);
if (response["error"] != 100)
document.getElementById('url1-reading').innerHTML = '---';
else
document.getElementById('url1-reading').innerText = response["response"];
},
function() {}
);
ajax_call("GET", "url2" , function(xhttp) {
response = JSON.parse(xhttp.responseText);
if (response["error"] != 100)
document.getElementById('url2-reading').innerHTML = '---';
else
document.getElementById('url2-reading').innerText = response["response"];
},
function() {}
);
console.log('Refresh');
}
setInterval(setup, 1000);
})();
This code behaves differently than what I expect. When I run this code, there are some times when the results that were suppose to go to url1 success_callback goes inside url2's success_callback.
To put another way the response variable inside url1 ajax_call is what I expected to show up as response variable for url2. So in effect the ajax_call seem to not know what success_callback is for what even though I explicitly pass it in as a parameter.
I'm coming from a C++ background so this is a difficult concept to grasp. How do I do this the right way? I hope my question is clear. Please tell me what is not clear so I can clarify.
The way you declare it, response is a global variable. Try changing response = to let response =

Json created to fit a structure

I have created a JSON like this one :
{"data":[{"content":"Event1","start":"new Date(2014,07,10)"},{"content":"Event2","start":"new Date(2014,07,17)"}],"success":true}
In order to fit the following code in Javascript :
data = [
{
'start': new Date(2010,7,23),
'content': 'Event'
},
{
'start': new Date(2010,7,23),
'content': 'Event'
},
];
Witth th JSON i have, i can easily access field, for example :
json.data[0].content
Return : "Event1"
My question is : how can i make the Javascript code "dynamic" to load every components in my JSON, assuming the fact that i don't know how many elements it will contains ?
Currently, i've done the followig code :
var xhr = new XMLHttpRequest();
xhr.open("GET", "/Test", true); // Call to a java servlet
xhr.send();
var json;
var jsonLength;
var data;
xhr.onreadystatechange = function(){
if(xhr.readyState == 4 && xhr.status == 200){
json = JSON.parse(xhr.responseText);
jsonLength = json.data.length;
}
}
data = [];
for(var i = 0 ; i < jsonLength ; i++){
data.push({
'start':json.data[i]['start'],
'content':json.data[i]['content']
})
}
timeline.draw(data);
EDIT : I don't even enter to the for loop ... Why ?
That's quite simple as these are just arrays and hash objects in JavaScript.
So you can just iterate over them:
for(var i = 0; i < json.data.length; i++) {
var item = data[i];
// Insert this into your data table
// Here you can use item which is set to the current item you are iterating over
}
JavaScript even let's you inspect your so you can look at the individual data item and find out what properties it has like this (see this question for details):
var keys = [];
for(var k in obj) keys.push(k);
UPDATE:
It seems you have fallen into the asynchrosity trap that JavaScript lays out.
The function xhr.onreadystatechange is only called once the event happens, the code below that function is executed instantly. So you where iterating over an empty dataset since the data you where looking at was not yet loaded.
JavaScript is very much callback based and especially with AJAX. Always keep in mind when the code will run, in this case xhr.onreadystatechange = function returns instantly and the code after continues to run. Only inside the function can you expect your variables to be set correctly.
var xhr = new XMLHttpRequest();
xhr.open("GET", "/Test", true); // Call to a java servlet
xhr.send();
var json;
var jsonLength;
var data;
xhr.onreadystatechange = function(){
if(xhr.readyState == 4 && xhr.status == 200){
json = JSON.parse(xhr.responseText);
jsonLength = json.data.length;
data = [];
for(var i = 0 ; i < jsonLength ; i++){
data.push({
'start':json.data[i]['start'],
'content':json.data[i]['content']
})
}
timeline.draw(data);
}
}
If your json is a string, just do
obj = JSON.parse(jsonString);
Then you'll have an object containing your json data, where you can access using obj[0].content (as an example)
Else, just iterate throught the json object, like Tigraine said.
(You question is a little bit unclear though)
try this:
var x={"data":[{"content":"Event1","start":"new Date(2014,07,10)"},{"content":"Event2","start":"new Date(2014,07,17)"}],"success":true};
for(i=0;i<x.data.length;i++)
{
console.log("content: "+x.data[i].content+" start: "+ x.data[i].start);
}
<script type="text/javascript">
var json = {
'data': [
{
'start': new Date(2010, 7, 23),
'content': 'Event'
},
{
'start': new Date(2010, 7, 23),
'content': 'Event'
},
]
};
alert(json['data'].length);
$(function() {
});
</script>

Error 'Illegal Invocation' while trying to convert javascript to jquery

I am trying to convert some code from javascript to jquery.
Javascript Code: (I have got this code here)
window.onload = function () {
document.getElementById('uploader').onsubmit = function () {
var formdata = new FormData(); //FormData object
var fileInput = document.getElementById('fileInput');
//Iterating through each files selected in fileInput
for (i = 0; i < fileInput.files.length; i++) {
//Appending each file to FormData object
formdata.append(fileInput.files[i].name, fileInput.files[i]);
}
//Creating an XMLHttpRequest and sending
var xhr = new XMLHttpRequest();
xhr.open('POST', '/Home/Upload');
xhr.send(formdata);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
alert(xhr.responseText);
}
}
return false;
}
}
JQuery Code: (According to my application)
$('#AutoUploadFiles').click(function () {
var formdata = new FormData();
var fileInput = $("#AutomaticUploader");
for (var i = 0; i < fileInput.get(0).files.length; i++) {
formdata.append(fileInput.get(0).files[i].name, fileInput.get(0).files[i]);
}
$.ajax({
url: '/members/AutoUploadFile',
type: 'post',
data: formdata,
success: function () {
},
error: function () {
}
});
});
When I try to execute the above JQuery code I get 'Illegal Invocation' error in jquery.min.js file.
I am new to Web Programming, so I might have done some mistakes while converting to JQuery.
If anybody catches some mistake, please guide me.
the problem is the formdata is an object and can't be serialize as an ordinary string
var formdata = new FormData();
and in your code
type: 'post',
data: formdata, //<-- this is the problem
success: function () {
formdata must be serialize well as valid json data or else it can't be send by $.ajax() that's why your jquery version will not work. Please try other jquery uploader scripts because there are lot of them in google
The accepted answer doesn't work if you are sending files over the XHR as file objects can not be JSON encoded.
The only "workaround" is to disable jQuery's XHR data processing.
To disable it globally use
$.ajaxSetup({processData:false});
or do
$.ajax({
... Ajax Stuff Here,
processData: false
});
on each request.

XMLHttpRequest not adding header - "X-Requested-With: XMLHttpRequest"

I have an ajax call where I used jQuery.ajax() to make a request to an mvc action. This all worked fine. However due to some forms having a file control I changed it from using jQuery.ajax() to using the XMLHttpRequest to send it using the HTML5 File API.
Since making this change the MVC action method no longer see's it as an ajax request. Using Fiddler2 I have noticed that it no longer adds the "X-Requested-With: XMLHttpRequest" to the request and I assume this is the problem.
The form I am trying to send does not have a file input in it, only normal textboxes etc, but I was trying to keep the method generic to deal with both. The following is the code I am using to send the ajax request:
// get the edit tender form
var $Form = $Button.closest('form');
var Url = $Form.attr('action');
var AjaxRequestObject = new XMLHttpRequest();
var FormDataToSend = new FormData();
$Form.find(':input').each(function () {
if ($(this).is('input[type="file"]')) {
var files = $(this)[0].files;
if (files.length > 0) {
FormDataToSend.append(this.name, files[0]);
}
} else {
FormDataToSend.append(this.name, $(this).val());
}
});
AjaxRequestObject.open('POST', Url, true);
AjaxRequestObject.onreadystatechange = function () {
if (AjaxRequestObject.readyState == 4) {
// handle response.
if (AjaxRequestObject.status == 200) {
if (!AjaxErrorExists(AjaxRequestObject.responseText, )) {
alert("success");
console.log(AjaxRequestObject.responseText);
}
else {
alert('failure');
}
}
else {
alert('failure');
}
}
};
AjaxRequestObject.send(FormDataToSend);
This code was provided following a problem I had which Darin Dimitrov provided the solution to, so I could send the file inputs by ajax.
Any ideas why this request would not send the header for an ajax call?
X-Requested-With is automatically added by jQuery. You can just as easily add it yourself with AjaxRequestObject.setRequestHeader(). Docs
I was having troubles with detecting if my request was ajax. So, maybe this sample will save someone a minute or two:
var xmlhttp = new XMLHttpRequest();
xmlhttp.open('GET', URL, true); // `true` for async call, `false` for sync.
// The header must be after `.open()`, but before `.send()`
xmlhttp.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
xmlhttp.onreadystatechange = function() {
// 4th state is the last:
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { ... }
};
xmlhttp.send();
Tested with Flask.
You can override natively all XMLHttpRequest.open method calls and add in it X-Requested-With header like:
(function () {
// #author https://github.com/stopsopa jfdsa78y453cq5hjfd7s877834h4h3
if (window.XMLHttpRequest.prototype.onOpen) {
return console.log('XMLHttpRequest.onOpen is already defined');
}
function over(method, on, off) {
var old = window.XMLHttpRequest.prototype[method];
if (!old.old) {
var stack = [];
window.XMLHttpRequest.prototype[on] = function (fn) {
if (typeof fn === 'function') {
stack.push(fn);
}
}
window.XMLHttpRequest.prototype[off] = function (fn) {
for (var i = 0, l = stack.length ; i < l ; i += 1 ) {
if (stack[i] === fn) {
stack.splice(i, 1);
break;
}
}
}
window.XMLHttpRequest.prototype[method] = function () {
var args = Array.prototype.slice.call(arguments);
var ret = old.apply(this, args);
for (var i = 0, l = stack.length ; i < l ; i += 1 ) {
stack[i].apply(this, args);
}
return ret;
}
window.XMLHttpRequest.prototype[method].old = old;
}
}
over('open', 'onOpen', 'offOpen')
XMLHttpRequest.prototype.onOpen(function () {
this.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
});
}());

why i can't parse xml in javascript?

hello i have problem to parse xml..
i have xml like this :
<tejemahan>
<kategori> komputer </kategori>
<hasil> aplikasi komputer </hasil>
</terjemahan>
Edited:
xml above I get in that way :
var url="http://localhost:8080/inlinetrans/api/translate/"+userSelection+"/"+hasilStemSel+"/"+hasilStem;
var client = new XMLHttpRequest();
client.open("GET", url, false);
client.setRequestHeader("Content-Type", "text/plain");
client.send(null);
if(client.status == 200)
alert("the request success"+client.responseText);
else
alert("the request isn't success"+client.status+""+client.statusText)
}
and this is my code to parse an xml file above :
this.loadXML = function (){
var url = http://localhost:8080/coba/api/artikan/"+sel+"/"+hasilStemSel+"/"+hasilStem
xmlDoc=document.implementation.createDocument("","",null);
xmlDoc.load("url");
xmlDoc.onload= this.readXML;
}
this.readXML = function() {
alert(xmlDoc.documentElement.tagName);
alert(xmlDoc.documentElement.childNodes[0].tagName);
alert(xmlDoc.documentElement.childNodes[1].tagName);
alert(xmlDoc.documentElement.childNodes[0].textContent);
alert(xmlDoc.documentElement.childNodes[1].textContent);
}
i can execute this code
xmlDoc=document.implementation.createDocument("","",null);
xmlDoc.load("url");
but why i can't execute this code
xmlDoc.load = this.readXML ???
Try putting the onload handler assignment before the load() call. If you call load() first, the onload event will happen before you have assigned a handler to handle it. Like this:
xmlDoc=document.implementation.createDocument("","",null);
xmlDoc.onload= this.readXML;
xmlDoc.load("url");
Firstly, I second David Dorward's suggestion: use XMLHttpRequest instead, which will work in all major browsers. Code is below.
Secondly, your readXML function is flawed, since most browsers will include whitespace text nodes within the childNodes collection, so xmlDoc.documentElement.childNodes[0] will actually be a text node and have no tagName property. I would suggest using getElementsByTagName() or checking the nodeType property of each node as you iterate over childNodes.
Thirdly, your XML is not valid: the <tejemahan> and </terjemahan> do not match, although this may be a typo in your question.
var url = "http://localhost:8080/coba/api/artikan/"+sel+"/"+hasilStemSel+"/"+hasilStem;
var readXML = function(xmlDoc) {
alert(xmlDoc.documentElement.tagName);
var kategori = xmlDoc.getElementsByTagName("kategori")[0];
alert(kategori.tagName);
};
var createXmlHttpRequest = (function() {
var factories = [
function() { return new XMLHttpRequest(); },
function() { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); },
function() { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); },
function() { return new ActiveXObject("Microsoft.XMLHTTP"); }
];
for (var i = 0, len = factories.length; i < len; ++i) {
try {
if ( factories[i]() ) {
return factories[i];
}
}
catch (e) {}
}
})();
var xmlHttp = createXmlHttpRequest();
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
readXML(xmlHttp.responseXML);
}
};
xmlHttp.open("GET", url, true);
xmlHttp.send(null);

Categories