I was wondering if there is any proper way to prevent ajax request from delivering random 404/500 Errors when calling many of them at the same time (synchronous or asynchronous)
e.g. a simple html table with some rows and columns to show a list of 500-800 people with some data
Way to go:
Getting ppl by selection (html form with organizational units) from the backend and write the resultlist in the first columns of the table
getting events of each person by his/her personId (result of the first request)
getting attributes of each person
getting roles for each person
getting calculated stuff from the backend for each person depending on their individual attributes,roles and events.
pseudocode:
function createTableData(){
var selected;
var personIds;
//get personIds by selection and write them into table
object.executeJSONRequest(...,
{ _ts: new Date().getTime(),
input: selected
},function(data) {
// write result into table
// fill resourceIds with result param
},..);
getEvents(personIds);
getAttribtues(personIds);
getRoles(personIds);
calculateStuff(personIds);
}
function getEvents(personIds){
object.executeGetRequest('...',
{ _ts: new Date().getTime(),
ppl: personIds
},function(data) {
//add result to table
}
}
function getAttributes(personIds){...} //and so on..
if i call all these methods in a row i sometimes get random errors sometimes while loading attributes, sometimes on loading roles, sometimes it all works fine.
if i call them nested in each ajax success block like
function createTableData(){
object.executeJSONRequest(...
{ _ts: new Date().getTime(),
input: selected
},function(data) {
getEvents(..);
});
}
function getEvents(..){
object.executeGETRequest(...
{ _ts: new Date().getTime(),
input: selected
},function(data) {
getAttributes(..);
});
}
function getAttributes(..){ ...,function(data){ getRole(..)}); and so on
it all works fine. If i try a solution with something like
document.ajaxStart/Stop(function(){ //if table columns i expected are filled do next}
i have to check all neccessary table colums if they are already filled with data or not.
Is there any really proper solution i just dind't think about?
(jQuery Version 1.2 /IE V7-8 ^^)
"If possible update jquery and ie versions"
First of all why are you calling multiple server calls in a single process.
It's better if you combine all the process into a single request and response cycle, do the required handling of data in java code.Don't go forth and back with request and response.
Any way you can use the jquery ajax which returns the status of the ajax call.
$.post("url",function(result,status){{
if(status == success){
//continue....
}else{
alert("Sorry something went wrong");
}
}});
Like this check all the request weather it successfully finished.
I strongly recommend you consider combining all the ajax calls into a single request.
Related
I am implementing infinite-scrolling in AngularJs. The below function gets called on a successful AJAX call, that takes place when:
The user scrolls to the end of screen.
The selects some filters, and hits the "Search" button.
In the first case, the data fetched from the AJAX call is appended to the existing list. In the second case, I intend to completely empty any existing data in the list, and display the new data. Here is my code to do that:
$scope.successCallBack=function(data){
$('#spn-model-buffering-image').hide(); //hide the loading spinner icon
if($scope.providersList === null) {
$scope.providersList = []; /* init if null */
}
if($scope.scrolled === 'true'){
/*If it was an scroll-end event, then simply append the new data to the existing one*/
Array.prototype.push.apply($scope.providersList, JSON.parse(data.serviceproviderlist)); //push the new data to the existing list
}
else{
/*If the user clicks on "Search Providers" button, then new data are fetched, and occupy the entire list view*/
$scope.providersList=[];
$scope.providersList=JSON.parse(data.serviceproviderlist);
}
viewToBeDisplayed(LIST_VIEW);
$scope.scrolled='true';
}
So, after a successful AJAX call, the above method is called. It hides the buffering image, and checks if the variable named scrolled is set to true. If yes, then it means that the event is not button-click, but the user has reached the end of screen, and hence, data have to be appended. Else, the user has clicked on the button, and hence, data have to be displayed fresh.
This is the function that gets called on button-click event:
$scope.getFilteredData=function(){
$scope.scrolled='false';
$scope.getMoreData();
}
My problem: View does not get updated. The AJAX call returns data as JSON. In the scroll-event, data are fetched and appended to the existing list, as expected.
Can someone suggest me what I might be doing wrong? Thanks!
Here is the AJAX call code:
$scope.getMoreData=function(){
$('#spn-model-buffering-image1').show(); //while the data are being fetched, display the loading spinner
$scope.updateAjaxData(); //update AJAX data: pagekey, category, and reftag
var url=$scope.getURL();
A.ajax(url, {
method: 'post',
params: AJAX_DATA,
success: function(data, s, x) {
$scope.successCallBack(data);
},
error: function(xhr, statusText, errorThrown) {
$scope.errorCallback(xhr);
}
});
}
Try to use the http provided by AngularJS.
$http.get('/someUrl', config).then(successCallback, errorCallback);
This is good practice and it will probably solve your problem of not updating the view.
Objective: Parse JSON from an API where results are listed across multiple pages.
I am new to JSON and to working with data in general. I want to know how to write a function that will update the url, outputting the results for each page, and stopping when it reaches one that is empty.
This problem here is from a Shopify url displaying JSON data used for trivial purposes and not part of a real application.
https://shopicruit.myshopify.com/admin/orders.json?page=1&access_token=c32313df0d0ef512ca64d5b336a0d7c6
Each page had 5O objects. I'm making an $.ajax request to the url but the url has page=1 as a query,
$.ajax({
url:"https://shopicruit.myshopify.com/admin/orders.json?page=1&access_token=c32313df0d0ef512ca64d5b336a0d7c6",
method:'get',
dataType:'JSON'
}).done(function(response){
so the response I am only getting back is only for The results of page one (obviously). I know there are more pages b/c if I manually put a 2 in place of the 1 I can see different data. This goes on for multiple pages. I have tried removing the page option, setting it to all and any and these just display page 1.I thought maybe leaving the page option out would cure the problem but it does not.
How do I get all the pages of data with an ajax call?
Is it a function that takes the $.ajaxcall inside of it, that adds page++ and makes a new call for each page? I still don't know how to write that sadly.
The shopify API docs do give some examples on how to display "all data" but I tried to use what they suggested and it did not work so I'm not sure that it's applicable to the problem, but just in case it is–
https://help.shopify.com/api/reference/order
Here is a simplistic answer - this will get pages until there's clearly no more data - i.e. once a page returns less than limit orders
function getAllData(page) {
return $.ajax({
url:"https://shopicruit.myshopify.com/admin/orders.json?page=" + (page || 1) + "&limit=250&access_token=c32313df0d0ef512ca64d5b336a0d7c6",
method:'get',
dataType:'JSON'
}).then(function(response){
if (page && response.orders.length == 250) {
return getAllData(page + 1)
.then(function (more) {
return response.orders.concat(more)
})
}
return response.orders;
});
}
getAllData(1).then(function(orders) {
// orders is an array of orders
});
Note I've used 250 for limit to get 250 at a time
I say this is simplistic because, it does get all the data, however, you need to wait until all the data is retrieved before you can use it - this may take too long for your "user experience" - but this should get you to a place you can start
There's logic in the code such that if page is 0, only the first page will be retrieved regardless of how many items are in it - so you could do something like
getAllData().then(function(page1data) {
// do something with page 1
}).then(function() {
return getAllData(2); // start at page 2
}).then(function(restOfData) {
// do something with restOfData, pages 2+
});
One thing I'm not sure of is
.then(function(response){
you may need to change this to
.then(function(r){
var response = r[0];
I'm not 100% certain of jQuery's .then callback arguments
I have a grid with data in Lighswitch application. Grid has on every column posibility to filter column. Thanks to lsEnhancedTable
Right now I am sending an ajax request to the web api controler with the list of ids of the Customers that I want to export. It works but with a lot of data it is very slow because I have to turn off the paging of the data to get all visible customers ids so I can iterate over the VisualCollection.
To optimize this I would have to turn on back the paging of the data to 50 records so that the initial load is fast and move the loading of the data to a save/export to excel button.
Possible solutions:
Load data all data on save button click. To do this I have to somehow load all items before I can iterate over collection.
The code bellow locks UI thread since the loadMore is async. How to load all data synchronously? Ideally I would like to have some kind of progress view using a msls.showProgress.
while(3<4)
{
if (screen.tblCustomers.canLoadMore) {
screen.tblCustomers.loadMore();
}
else
break;
}
var visibleItemsIds = msls.iterate(screen.tblCustomers.data)
.where(function (c) {
return c;
})
Second approach would be turn on paging and pass just the filters applied by the users to the web api controller so I can query database and return only filtered records. But I don't know how to do that.
Third approach is the one that I am using right now. Turn off the paging->iterate over visual collection, get the customers id, pass them to the controller and return a filtered excel. This doesn't work well when there are a lot of records.
Iterate over filtered collection in the server side? I don't know if there is a way to do this in Lighswitch?
Here's an option for client side javascript.
// First build the OData filter string.
var filter = "(FieldName eq " + msls._toODataString("value", ":String") + ")";
// Then query the database.
myapp.activeDataWorkspace.ApplicationData.[TableName].filter(filter).execute().then(function (result) { ... });
I'm actually running into little problems with my current project. Following case:
I've got a model called "Posting" with relations:
public function subscribers(){
return $this->belongsToMany('User');
}
In my view-file there is a table containing all Postings and also a checkbox for subscribing/unsubscribing with the matching value to the posting-id:
<input class="click" type="checkbox" name="mobileos" value="{{{$posting->id}}}"
#if($posting->subscribers->find(Auth::User()->id))
checked="checked"
#endif
>
Now the thing I want to archive:
A JavaScript is going to watch if the checkbox is checked or not. According to that, the current user subscribes/unsubscribes to the posting. Something like:
$('.click').on('click',function() {
// $posting->find(---$(this).prop('checked')---)->subscribers()->attach(---Auth::user()->id---);
// $posting->find(---$(this).prop('checked')---)->subscribers()->detach(---Auth::user()->id---);
});
Is there any possibility to archieve that or any other ways? I couldn't get my head around this so far.
Cheers,
Chris
If you want to use Ajax to achieve this, you will need a REST endpoint in Laravel for the subscriptions, e.g.:
http://localhost/subscribe/{{userid}}
When this Endpoint is called, the database can be updated. The function could also return a JSON showing, if the saving database in the database successful.
Use this endpoint to make an Ajax Call on click:
var user = {
id: 0 // retrieve the correct ID from wherever it is stored
}
$('.click').on('click',function() {
$.GET('http://localhost/subscribe/' + user.id,
function () { // this is the success callback, that is called, if the Ajax GET did not return any errors
alert('You are subsribed')
});
});
Ideally you won't be using the GET method, but instead use POST and send the user ID as data. Also you would need to retrieve the user ID from session or wherever it is stored.
Take care that as you are using Ajax it can easily be manipulated from the client side. So on the server you should check, if the user ID that was sent is the same as in the Session. Maybe you don't need to send the user id at all, but that depends on how your backend is built.
I'm very, very new to Javascript, and to web programming in general. I think that I'm misunderstanding something fundamental, but I've been unable to figure out what.
I have the following code:
function checkUserAuth(){
var userAuthHttpObject = new XMLHttpRequest();
var url = baseURL + "/userAuth";
userAuthHttpObject.open("POST",url,true);
userAuthHttpObject.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
userAuthHttpObject.onload=function(){
if (userAuthHttpObject.readyState == 4) {
var response = json.loads(userAuthHttpObject.responseText);
return response; //This is the part that doesn't work!
}
};
userAuthHttpObject.send(params);
}
I would love to call it from my page with something like:
var authResponse = checkUserAuth();
And then just do what I want with that data.
Returning a variable, however, just returns it to the userAuthObject, and not all the way back to the function that was originally called.
Is there a way to get the data out of the HttpObject, and into the page that called the function?
Working with AJAX requires wrapping your head around asynchronous behavior, which is different than other types of programming. Rather than returning values directly, you want to set up a callback function.
Create another JavaScript function which accepts the AJAX response as a parameter. This function, let's call it "takeAction(response)", should do whatever it needs to, perhaps print a failure message or set a value in a hidden field and submit a form, whatever.
then where you have "return response" put "takeAction(response)".
So now, takeAction will do whatever it was you would have done after you called "var authResponse = checkUserAuth();"
There are a couple of best practices you should start with before you continue to write the script you asked about
XMLHTTTPRequest() is not browser consistent. I would recommend you use a library such as mootools or the excellent jquery.ajax as a starting point. it easier to implement and works more consistently. http://api.jquery.com/jQuery.ajax/
content type is important. You will have have problems trying to parse json data if you used a form content type. use "application/json" if you want to use json.
true user authorization should be done on the server, never in the browser. I'm not sure how you are using this script, but I suggest you may want to reconsider.
Preliminaries out of the way, Here is one way I would get information from an ajax call into the page with jquery:
$.ajax({
//get an html chunk
url: 'ajax/test.html',
// do something with the html chunk
success: function(htmlData) {
//replace the content of <div id="auth">
$('#auth').html(htmlData);
//replace content of #auth with only the data in #message from
//the data we recieved in our ajax call
$('#auth').html( function() {
return $(htmlData).find('#message').text();
});
}
});