Ajax events error when sending multiple http request - javascript

when i'm try to get data for some html element from a website by ajax i added some events like xhr.onloadstart,xhr.onloadend to show the loader element before sending the request and adding the data after finishing the response and hide the loader
the problem is when i try to click on multiple elements after each other it's just stop working just display the load for some html elements and not given any data and that's happening just when i try to click on 3 or 4 element after each other directly - and when i click normally and wait for load it's working without any problems -- i don't know if the problem is with my code or the problem in ajax like it's cannot handle many requests at the same time ... Please anyone help me
i was working with jquery ajax and changed to the XMLHttpRequest() and the problem still the same
Here's my code
for(let q = 0; q < elem.length; q++) {
elem[q].addEventListener("click",function() {
let url = $(this).find(".elem").attr("href");
let _this = this;
let $this = $(this);
var xh = new XMLHttpRequest();
xh.onloadstart = function(bubbles) {
_this.getElementsByClassName("loader")[0].style.display = 'block';
}
xh.onreadystatechange = function(change) {
_this.getElementsByClassName("loader")[0].style.display = 'none';
}
xh.onloadend = function(data) {
console.log(data)
//result dom object
console.log($(data.currentTarget.responseText)[71].getElementsByClassName("row").length)
if($(data.currentTarget.responseText)[71].getElementsByClassName("row").length > 0) {
let row = $(data.currentTarget.responseText)[71].getElementsByClassName("row")[0].getElementsByClassName("row")[0];
let select_color = $(row).find("#container #color_select_options").attr("class","ElemData");
$this.append(select_color[0]);
//when user click again delete appended element and keep the first one
if($this.find(".ElemData").length > 1) {
for(o = 1; o < $this.find(".ElemData").length; o++) {
_this.getElementsByClassName("ElemData")[o].remove()
}
}
}
})
}

Related

Javascript function doesn't trigger

$("tbody").on('click', '#update', function () {
$("#UpdateModal").modal("show");
var id = $(this).data("id");
console.log(id);
$.ajax({
type: 'Get',
url: "/Users/GetUser?id=" + id,
data: {
"cusid": id
},
success: function (response) {
console.log(response);
console.log(response.data.userName);
var departments = #Html.Raw(Json.Serialize(#ViewBag.departments));
var duties = #Html.Raw(Json.Serialize(#ViewBag.duties));
var roles = #Html.Raw(Json.Serialize(#ViewBag.roles));
$('#UpdateModal #Id').attr('value', response.data.id);
$('#UpdateModal #UserName').attr('value', response.data.userName);
$('#UpdateModal #FirstName').attr('value', response.data.firstName);
$('#UpdateModal #LastName').attr('value', response.data.lastName);
$('#UpdateModal #Password').attr('value', response.data.password);
$("#UpdateModal #DepartmentId option:first-child").prop("selected", "selected").text(response.data.departmentName);
$("#UpdateModal #DutyId option:first-child").prop("selected", "selected").text(response.data.dutyName);
$("#UpdateModal #RoleId option:first-child").prop("selected", "selected").text(response.data.roleName);
if (response.data.isActive) {
$("#UpdateModal #IsActive #true").prop("selected", "true")
console.log(response.data.isActive);
}
else {
$("#UpdateModal #IsActive #false").prop("selected", "false")
console.log(response.data.isActive);
}
for (var i = 0; i < departments.length; i++) {
if (response.data.departmentName == departments[i].departmentName) { $("#UpdateModal #DepartmentId option:first-child").prop("selected", "selected").val(departments[i].id); }
}
for (var i = 0; i < duties.length; i++) {
if (response.data.dutyName == duties[i].dutyName) {
$("#UpdateModal #DutyId option:first-child").prop("selected", "selected").val(duties[i].id);
}
}
for (var i = 0; i < roles.length; i++) {
if (response.data.roleName == roles[i].roleName) { $("#UpdateModal #RoleId option:first-child").prop("selected", "selected").text(response.data.roleName).val(roles[i].id); }
}
}
});
});
What I want to do here is to pull the data into my update modal with API. But it can't do it. Actually it was working before but suddenly the code stopped working. Can anyone see the error?
What do I need to do for this function to work? It gets triggered when I use the same code in another view. But it never gets triggered here. Please help.
There could be multiple reasons why this code is not working. Here are a few possible solutions:
1 - Check if the target element (#update) exists in the DOM when the click event handler is attached to it. If the element is dynamically generated, you may need to use event delegation, as follows:
$("tbody").on('click', '#update', function() {}
2 - Verify if the AJAX request is being sent and if the server is returning a valid response. You can use the browser's network tab or your browser's developer tools to see the network requests and the responses.
3 - Check the values of id, departments, duties, and roles in the console. They should have valid values.
4 - Ensure that the selectors used in the code are correct and that they match the actual HTML structure. You can use your browser's developer tools to inspect the elements and see if the selectors match the elements.
5 - Make sure that the jQuery library is loaded correctly and that there are no errors in the console.

Javascript: Am I using onreadystatechange properly?

Bare in mind I am very new to JavaScript syntax, so please have patience.
I'm trying to use multiple onreadystatechange's as promises to catch what I return from express, but every time I do, both of them are getting called. Here is my code:
var ready = function(){
xhr.open('GET', 'getallbeertypes');
xhr.send(null);
xhr.onreadystatechange = function () {
var parent = document.getElementById('recipes');
var docfrag = document.createDocumentFragment();
if(xhr.status == 200){
var beerTypes = JSON.parse(xhr.responseText);
//loop through beerTypes to append a button to each list item
for (var beer = 0; beer < beerTypes.length; beer++){
//create necessary elements
var li = document.createElement('li');
var button = document.createElement('BUTTON');
//set text content to list item
li.textContent = beerTypes[beer].alias;
//append list item to button
button.appendChild(li);
// add onclick attribute
button.setAttribute("name", beerTypes[beer]._id);
button.setAttribute("onclick", "moreInfo(this.getAttribute('name'))");
//append button to document fragment
docfrag.appendChild(button);
}
//display on DOM element
parent.appendChild(docfrag);
}else{
// console.log(JSON.parse(xhr.responseText));
var header = document.createElement('h1');
header.textContent = "Something went wrong. Please try again later.";
docfrag.appendChild(header);
parent.appendChild(header);
}
}
}
ready();
So the above section of code works, and it displays each JSON object as a button in a list of items. When the button is clicked, the following function is supposed to run:
var moreInfo = function(_id){
xhr.open('GET', '/getuserrecipes/' + _id);
xhr.send();
xhr.onreadystatechange = function(){
console.log("is this running?");
console.log(JSON.parse(xhr.responseText));
}
}
I'm expecting the onclick attribute should only run the moreInfo function.
Whenever I click one of the buttons, the else statement in the ready function is somehow running and displays Something went wrong. Please try again later on the screen.
The only connection I can make is the onreadystatechange, but I don't really know if that's it.
How/why is the other function even being called and How can I stop it? All help is appreciated.
You should check for the state of the request. To do that, use readyState property. There are 5 states, integers from 0 to 4, and you want the last one, which is 4.
something like this:
if (xhr.readyState == 4 && xhr.status == 200){
...
}
Check this example.

How would you cycle through each image and check it for an error in a casperjs script?

How would you cycle through every image on a given page and check to see if it was loaded or errored out?
The following are not seeming to work in the phantomjs/casperjs setup yet cycling through and grabbing the src is working.
.load()
and
.error()
If the above does work, could someone show a proper usage that would work in a casperjs script?
The code I used looked similar to the following:
var call_to_page = this.evaluate(function() {
var fail_amount = 0;
var pass_amount = 0;
var pass_img_src = [];
var fail_img_src = [];
var img_src = [];
$("img").each(function(){
$(this).load(function(){
pass_amount++;
pass_img_src.push($(this).attr("src"));
}).error(function(){
fail_amount++;
fail_img_src.push($(this).attr("src"));
});
img_src.push($(this).attr("src"));
});
return [img_src, fail_amount, fail_img_src, pass_amount, pass_img_src];
});
Any help as to why the above code doesnt work for me would be great. The page is properly being arrived upon and I am able to mess with the dom, just not .load or .error. Im thinking its due to the images being done loaded, so Im still looking for alternatives.
CasperJS provides the resourceExists function which can be used to check if a particular ressource was loaded. The ressource is passed into a function, so custom constraints can be raised.
casper.then(function(){
var fail_amount = 0;
var pass_amount = 0;
var pass_img_src = [];
var fail_img_src = [];
var elements = this.getElementsInfo("img");
elements.forEach(function(img){
if (img && img.attributes && casper.resourceExists(function(resource){
return resource.url.match(img.attributes.src) &&
resource.status >= 200 &&
resource.status < 400;
})) {
pass_amount++;
pass_img_src.push(img.attributes.src);
} else {
fail_amount++;
fail_img_src.push(img.attributes.src);
}
});
this.echo(JSON.stringify([fail_amount, fail_img_src, pass_amount, pass_img_src], undefined, 4));
});
This can be done after the page is loaded. So there is no need to preemptively add some code into the page context.
In turn, the problem with you code may be that the callbacks never fire because the images are already loaded of already timed out. So there is no new information.
If you're not sure what kind of errors are counted, you can use a custom resources detection for all available types or errors.
var resources = []; // a resource contains at least 'url', 'status'
casper.on("resource.received", function(resource){
if (resource.stage == "end") {
if (resource.status < 200 || resource.status >= 400) {
resource.errorCode = resource.status;
resource.errorString = resource.statusText;
}
resources.push(resource);
}
});
casper.on("resource.timeout", function(request){
request.status = -1;
resources.push(request);
});
casper.on("resource.error", function(resourceError){
resourceError.status = -2;
resources.push(resourceError);
});
function resourceExists(url){
return resources.filter(function(res){
return res.url.indexOf(url) !== -1;
}).length > 0;
}
casper.start(url, function(){
var elements = this.getElementsInfo("img");
elements.forEach(function(img){
if (img && img.attributes && resourceExists(img.attributes.src) && !resourceExists(img.attributes.src).errorCode) {
// pass
} else {
// fail
}
});
});
I don't have much experience with caperjs, in my observation I identified below points
Note:
jQuery .load( handler ) and .error( handler ) both were deprecated from verson 1.8.
If you're using jQuery 1.8+ then attaching load and error events to img(tags) does nothing.
jQuery Ajax module also has a method named $.load() is shortcut form of $.get(). Which one is fired depends on the set of arguments passed.
Here are Caveats of the load event when used with images from jQuery Docs
A common challenge developers attempt to solve using the .load() shortcut is to execute a function when an image (or collection of images) have completely loaded. There are several known caveats with this that should be noted. These are:
It doesn't work consistently nor reliably cross-browser
It doesn't fire correctly in WebKit if the image src is set to the same src as before
It doesn't correctly bubble up the DOM tree
Can cease to fire for images that already live in the browser's cache
So if you've version 1.8+ of jQuery the below block does nothing.
$(this).load(function(){
pass_amount++;
pass_img_src.push($(this).attr("src"));
}).error(function(){
fail_amount++;
fail_img_src.push($(this).attr("src"));
});
As a result this return [img_src, fail_amount, fail_img_src, pass_amount, pass_img_src]; statement will give us only img_src[with number of imgs as length] array filled with srcs of imgs in page. and other elements fail_amount, fail_img_src, pass_amount, pass_img_src will have same defaults all the time.
In the case of jQuery 1.8 below load and error events attachment with jQuery were meaningful(in your case these events were attached after they were loaded on page, so they won't show any effect with load and error callbacks), but the time where we attach events matters. We should attach these before the img tags or place the events in tag level(as attributes onload & onerror) and definitions of function handlers script should keep before any img tag or in very beginning of the body or in head
There're ways to figure out some are here:
use open-source plug-in like (Use imagesLoaded](https://github.com/desandro/imagesloaded)
Can use ajax call to find out whether the img.src.url were good or not?
Dimension based check like below function IsImageRendered
below I've but its old one not sure the browser support at this time. i recommend to go with above plug in if you can use it
var call_to_page = this.evaluate(function () {
function isImageRendered(img) {
// with 'naturalWidth' and 'naturalHeight' to get true size of the image.
// before we tried width>0 && height>0
if (typeof img.naturalWidth !== "undefined" && img.naturalWidth === 0) {
return false;
}
//good
return true;
}
var pass_img_src = [];
var fail_img_src = [];
var img_src = [];
$("img").each(function () {
var $img = $(this), $srcUrl = $img.attr("src");
img_src.push($srcUrl);
if (!$srcUrl)
fail_img_src.push($srcUrl);
else {
if (isImageRendered($img.get(0))) {
pass_img_src.push($srcUrl);
}
else {
fail_img_src.push($srcUrl);
}
}
});
var fail_count = fail_img_src.length,
pass_count = pass_img_src.length;
return [img_src, fail_count, fail_img_src, pass_count, pass_img_src];
});

Extract URL data from XMLHttpRequest

here is my javaScript code:
window.addEventListener('load', function() {
var submitimages = document.getElementById('submitimages');
submitimages.addEventListener('click', upload);
var images = document.getElementById('images');
});
var upload = function(event) {
event.preventDefault();
event.stopPropagation();
var data = new FormData();
for(var i = 0; i < images.files.length; ++i) {
data.append('images[]', images.files[i]);
}
var xhr = XMLHttpRequest();
xhr.open('POST', 'upload.php?test=' + 'test', true);
xhr.send(data);
}
My objective is to upload multiple images using form data and I want those sent images to move on a different directory depending on text that is on the url upload.php?test=' + 'test' where as on my example I want to move those image to test folder
and here is my php code so far
Please help I tried everything I know but I think I need idea whos someone is more knowledgeable to JavaScript. Regards

Phonegap onDeviceOnline

I am using the folowing script to check if device is online or offline:
function checkConnection() {
document.addEventListener("online", onDeviceOnline, false);
document.addEventListener("offline",onDeviceOffline, false);
function onDeviceOnline(){
loadZive();
loadMobil();
loadAuto();
};
function onDeviceOffline(){
alert("deviceIsOffline");
};
};
checkConnection();
Then I have this function to load feed:
function loadZive(publishedDateConverted){
google.load("feeds", "1");
function initialize() {
var feed = new google.feeds.Feed("http://www.zive.sk/rss/sc-47/default.aspx");
feed.setNumEntries(window.localStorage.getItem("entriesNumber"));
feed.load(function(result) {
if (!result.error) {
var feedlist = document.getElementById("feedZive");
for (var i = 0; i < result.feed.entries.length; i++) {
var li = document.createElement("li");
var entry = result.feed.entries[i];
var A = document.createElement("A");
var descriptionSettings = window.localStorage.getItem("descriptionSettings");
if (descriptionSettings=="true"){
var h3 = document.createElement("h3");
var p = document.createElement("p");
var pDate = document.createElement("p");
pDate.setAttribute("style","text-align: right; margin-top: 5px;");
var publishedDate = new Date(entry.publishedDate);
publishedDateConverted = convertTime(publishedDate);
pDate.appendChild(document.createTextNode(publishedDateConverted));
h3.setAttribute("style","white-space: normal;")
h3.appendChild(document.createTextNode(entry.title));
p.setAttribute("style","white-space: normal;")
p.appendChild(document.createTextNode(entry.content));
A.setAttribute("href",entry.link);
A.appendChild(h3);
A.appendChild(p);
A.appendChild(pDate);
}
else{
A.setAttribute("href",entry.link);
A.setAttribute("style","white-space: normal;")
A.appendChild(document.createTextNode(entry.title));
};
li.appendChild(A);
feedlist.appendChild(li);
}
$("#feedZive").listview("refresh");
}
});
}
google.setOnLoadCallback(initialize);
};
First I load second script, then first. But I cant see anything. If I turn my app on then I see page layout for abou 1 sec then (probably after loading first script) function onDeviceOnline() happens and I can see only blank page. But it should load feeds into existing template.
IMHO onDeviceOnline function happens after loading the page template and therefore it cant import feeds. If I create function like this:
function loadFeeds(){
loadZive();
loadMobil();
loadAuto();
};
then everything works fine so I think it has something to do with online and offline eventlisteners. It also didnt work when I put checkconnection into onDeviceReady function so it should not be the problem. So is there any way to check if device is online and if it is then use js file to load feeds?
EDIT: I have used Simon McDonald suggestion and created code like this:
function onDeviceReady(){
document.addEventListener("backbutton", onBackKeyDown, false);
function onBackKeyDown(){
navigator.app.exitApp();
}
function checkConnection() {
var networkState = navigator.network.connection.type;
if (networkState == "none"){
alert("no network connection");
}
else{
loadZive();
loadMobil();
loadAuto();
};
};
checkConnection();
};
With this code alerts are working perfectly for device online and device offline but when I try to loadFeed I get the same result as before (page layout loads and then everything changes to blank page).
The problem is that you are adding a "online" event listener in device ready event listener but the device is already on line so the event will not fire again until there is a change in connectivity. In your device ready event listener you should check the value of navigator.connection.network.type and make sure it isn't NONE.
http://docs.phonegap.com/en/2.0.0/cordova_connection_connection.md.html#connection.type

Categories