How to extend jQuery's AJAX function - javascript

I've played around with creating my own jquery functions, this done via the
$.fn.extend({
myFunc: function () {
}
});
However, after scouring the web and SO for an answer, I would like to ask:
How can I extend $.ajax()
The new implementation of $.ajax can be used by running
$.ajax({
}).done(function (e) {
}).fail(function (e) {
});
What I would like to do is to add a .progress() so that I don't always have to write
$.ajax({
url: path,
xhrFields: {
onprogress: function (e) {
if (e.lengthComputable) {
console.log(e.loaded /e.total * 100 + '%');
}
}
}
});
each time I want to monitor the progress. e.g.
$.ajax({
url: '/somewhereorother',
type: 'post',
dataType: 'json'
}).progress(function (e) {
updateProgressBar(e.percentage + '%');
}).done(function (e) {
}).fail(function (e) {
});

$.ajax is a function attached to $ object.
As such, to extend it you would have to store the reference to it somewhere, and call it when needed, something like:
var ajax = $.ajax;
$.ajax = function()
{
if (!arguments[0].success)
arguments[0].success = function()
{
window.alert('done!');
}
ajax.apply(ajax, arguments);
}
This is a concept (I'm not sure of this scope in apply - would have to actually run it) ;) Also, I'd say it's ugly as hell way of doing things.
If you want your $.ajax function to differ from official function, I'd still separate it. Either via $.my_ajax or by separate namespace (take a look at http://api.jquery.com/jquery.sub/)

Related

Is using jQuery clever to download multiple template-files?

I want to download and cache multiple mustache-templates and the only real way I know to do this is by downloading them via the jQuery.ajax()-method.
So my straightforward preload-init code looks a little ... ugly!
function getAllTemplatesUglyAndNotPerformant() {
//this is no longer valid, stays just for reference; look at the bottom for the solution
//easy - preload the template and execute it to the data
$.ajax({
url: 'fragments/employee.mustache',
success: function (employeeTpl) {
//uh-oh async process-handling forces me into digging this deeper
$.ajax({
url: 'fragments/employee_day.mustache',
success: function (dayTpl) {
//third level - now i am puzzled already
$.ajax({
url: 'fragments/employee_day_regular.mustache',
success: function (protodayTplRegular) {
//monologue: am i doing this right?
$.ajax({
url: 'fragments/employee_day_deleted.mustache',
success: function (protodayTplDeleted) {
//most probably not
var cachedTemplates = {
employee: employeeTpl,
day: dayTpl,
protoday: {
regular: protodayTplRegular,
deleted: protodayTplDeleted
}
};
//shoot, i also cannot return cachedTemplates, better bury my init-method in this!
init(cachedTemplates);
}
});
}
});
}
});
}
});
}
//initializes downloading and parsing data to what will be seen
function init(cachedTemplates) {
//get the data
$.ajax(
url: '_get_data.php',
success: function (data) {
if (data.success) {
$.each(data.employees, function (iEmployee, vEmployee) {
//this goes through a custom rendering for an employee and his sub-nodes stored in arrays (all rendered in Mustache)
var employee = parseEmployee(vEmployee);
var html_employee = employee.render(cachedTemplates);
$('#data-position').append(html_employee);
});
}
//ignore what may else happen for now
}
)
}
Is there a better way for downloading multiple files for caching in JS?
EDIT:
my rewrite of getAllTemplates() looks now more like this and is finally "more-understandable" and performant for the next one to touch "Peters Legacy":
function getAllTemplates() {
$.when(
$.get('fragments/employee.mustache'),
$.get('fragments/employee_day.mustache'),
$.get('fragments/employee_day_regular.mustache'),
$.get('fragments/employee_day_deleted.mustache')
)
.done(function (employeeTpl, acquisitionTpl, protodayTplRegular, protodayTplDeleted) {
var cachedTemplates = {
employee: employeeTpl[0],
acquisition: acquisitionTpl[0],
protoday: {
regular: protodayTplRegular[0],
deleted: protodayTplDeleted[0]
}
};
init(cachedTemplates);
});
}
You don't specify which version of jQuery you're using, so here's assuming you're using a somewhat current build;
You can use $.when() which is in jQuery 1.5+.
$.when() allows you to bundle (essentially) a bunch of async methods (ajax in this case) and wait until all of them have completed. In your example you are firign one request, waiting for the response and then firing another. With $.when(); if your connection allows it they can all fire simultaneously, saving a lot of time in your example!
something like:
$.when(
$.ajax( "fragments/employee.mustache" ),
$.ajax( "fragments/employee_day.mustache" ),
$.ajax( "..." )
)
.done(function( employeeRes, dayRes ) {
// the first item in array should be the data
var employeeTpl = employeeRes[0];
var dayTpl = dayRes [0];
// ...
});
There's loads of good examples at the jQuery Website

Showing a loading div during a jQuery ajax call

Im trying to show a loading div while waiting for an ajax call to complete. I have tried a couple of methods but cant seem to get anything to work consistently.
with my current code it works if i have a break point on the function that shows the div once the ajax is complete.
Fiddle
var https = 'https://www.googleapis.com/calendar/v3/calendars/';
function HideCheckShowLoading(checkId) {
$("#check_" + checkId).hide('slow', function() {
$("#loading_" + checkId).show('slow');
});
};
function HideLoadingShowCheck(checkId) {
$("#loading_" + checkId).finish().hide('slow', function() {
$("#check_" + checkId).finish().show('slow');
});
};
$(document).ready(function() {
$('#get').click(function() {
HideCheckShowLoading(1);
$.ajax({
url: https,
dataType: 'jsonp',
type: "GET",
success: function(response) {
//do something
},
error: function() {
//do something else
}
}).done(function() {
HideLoadingShowCheck(1)
});
});
$('#get2').click(function() {
HideLoadingShowCheck(1);
});
});
#check_1
{
background-color:red;
}
#loading_1
{
background-color:blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="check_1">Check</div>
<div hidden id="loading_1">LOADING</div>
<button id="get">Get</button>
<button id="get2">Get2</button>
What i would like to happen is,
on the click of a button we hide the check div
we show the loading div
make the ajax call
if successful do something(Reload the contents of the check div)
hide the loading div
show the check div
As said I have tried a few methods that i have found but i repeatedly get stuck with just the loading div shown
Thanks
I believe you may be slightly over-complicating things here. Something simple like this would suffice:
$('#get').click(function() {
HideCheckShowLoading();
$.ajax({
url: https,
dataType: 'jsonp',
type: "GET",
success: function (response) {
//do something
},
error: function() {
//do something else
},
complete: HideLoadingShowCheck
});
});
If you don't want the HideLoadingShowCheck routine to happen after success or error (standard behavior of complete), you can just move a function call HideLoadingShowCheck(); into your success and error blocks instead of using complete.
When you add () to a function name, it calls it immediately and returns the result. What you want to do is pass the function itself, not the result of the function - and you do that without the ().
There's no need for the $.when (assuming HideCheckShowLoading() doesn't make an ajax call, the jquery animations work differently), and $.ajax returns the promise itself, so you can update your code to:
$(document).ready(function() {
$('#get').click(function() {
HideCheckShowLoading();
$.ajax({
url: https,
dataType: 'jsonp',
type: "GET",
success: function (response) {
//do something
},
error: function() {
//do something else
}
})
//.done(HideLoadingShowCheck);
.done(function() { HideLoadingShowCheck(otherparams); })
});
});
I would change the showcheck function to add .finish() incase it's still animating from the showhide:
function HideLoadingShowCheck() {
$("#loading").finish().hide('slow',function () {
$("#check").finish().show('slow');
});
};

How to check if my container fully load is completed?

I have an issue, do not know if it possible or not, how to check if my container is already loaded or not, because sometimes it is being loaded faster, sometimes slower and if it does not succeed in time getting an error in javaScript where gridview some functions are not recognizable(because the gridview is not loaded fast enough). Hope it is clear. Thanks for Your time.
Code:
function LoadPartial(partialUrl, container) {
$.ajax({
type: 'POST',
url: partialUrl,
success: function (returnData) {
$(container).html(returnData);
}
});
//.done(function () {
// return;
//});
}
you can use something like this.
$(".container").load(function (){
alert("Loaded :)");
});
Let me know in-case this doesn't work.
You can try using .data()
if ($('#mycontainer').data('loaded')) {
// your code
}
If you mean to find event when data received use "complete" function:
$.ajax({
type: 'POST',
url: partialUrl,
success: function (returnData) {
$(container).html(returnData);
},
complete: function() {
console.log('container filled with data');
}
});

Generic way to handle all AJAX calls

Is there a way to detect all AJAX calls (both GET and POST)? I need to do a generic way to show a loading div while the AJAX call process are running. Something like the code below:
$.ajax({
url: 'my/url',
type: "GET",
dataType: "json",
beforeSend: function() {
$('#loading').show();
},
success: function() {
$('#loading').hide();
// do some stuff...
}
Instead to call in every AJAX beforeSend() and success() behaviors (show and hide the loading div), I'm searching a generic way to handle it. When I have an AJAX call, I just do it:
$.ajax({
url: 'my/url',
type: "GET",
dataType: "json",
success: function() {
// do some stuff...
}
When that beforeSend() behavior is implicity in this request and the same for the success() hide behavior. Do you have any idea how can I treat this thing?
Thank you all!
Yes, you can do this using .ajaxStart() & .ajaxStop() methods like:
$(document).ready(function () {
$(document).ajaxStart(function () {
$('#loading').show();
}).ajaxStop(function () {
$('#loading').hide();
});
});
Funnily enough, I was trying to do this myself this morning!
$('#loading').bind('ajaxSend', function() {
$(this).show();
}).bind('ajaxStop', function() {
$(this).hide();
}).bind('ajaxError', function() {
$this.hide();
});
Obviously, lots of different ways to achieve this, but I prefer to bind the visibility of the loading message to the AJAX events, rather than the other way around...

jQuery ajax asyncrhonous calling

I'm trying to make some actions after an ajax call done with jquery.
I have seen that if i use a function like this:
function DownloadData() {
$.ajax({
url: "/api/AlbumsRest",
accepts: "application/json",
cache: false,
success: function () {
/*binding stuff*/
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert('Error' + textStatus);
}
});
}
The ajax request it's done in async mode. I don't want to change it because i don't want to freeze the page. But i would like to make some actions (animations, effects etc) after this ajax is completed.
So, my question is, how can i to know if i'm at the end of this request without using the success event
If i call DownloadData function like this:
function DownloadNextData() {
DownloadData();
SlideOutAnimation();
SlideInAnimation();
}
I need to make slides after async request has been made.
Some idea ?
Using jQuery Deferred Objects you should return the result of $.ajax() from DownloadData
function DownloadData() {
return $.ajax({...});
}
and then you can register a function outside of your AJAX handler that'll only get called once the AJAX call has completed:
function DownloadNextData() {
DownloadData().done(function() {
SlideOutAnimation();
SlideInAnimation();
});
}
behold - your animation processing is completely decoupled from your AJAX function :)
To simplify things, .done can also actually take a list of function references:
function DownloadNextData() {
DownloadData().done(SlideOutAnimation, SlideInAnimation);
}
Note that in this case you can't supply your own function arguments - they'll actually get passed the contents of the AJAX data.
function DownloadData() {
return $.ajax({
url: "/api/AlbumsRest",
accepts: "application/json"
});
}
function DownloadNextData() {
SlideOutAnimation();
SlideInAnimation();
}
DownloadData().done(DownloadNextData);
Try $.ajaxcomplete. here is the documentation for it http://api.jquery.com/ajaxComplete/

Categories

Resources