JQuery 1.11.1 Deferred Then - multiple with parameters - javascript

I am having issued chaining a bunch of deferred 'then's in my javascript function.
In JQuery 1.7.2 I was able to create something like the following example, passing parameters from each one to determine if I continue.
myAjaxFunction(myParametersObject)
.done(function (noErrors) {
if (anyErrors == true) {
// call ajax routine
return true;
} else {
//stop code execution
return false;
}
})
.then(function (noErrors) {
if (anyErrors == true) {
// call ajax routine
return true;
} else {
//stop code execution
return false;
}
})
.then(function (noErrors) {
if (anyErrors == true) {
// call ajax routine
return true;
} else {
//stop code execution
return false;
}
})
.then(function (noErrors) {
if (anyErrors == true) {
// final code here
}
});
It works perfectly on JQuery 1.7.2 but I am working on a project that requires JQuery 1.11.1 and this no longer works.
How can I pass parameters to the upcoming 'then' in JQuery 1.11.1?

Return jQuery promise value from myAjaxFunction appear to be defined as noErrors at done handler argument parameter
.done(function (noErrors) {
within .done handler as anyErrors ?
if (anyErrors == true) {
similarly at
.then(function (noErrors) {
if (anyErrors == true) {
// call ajax routine
?
Try setting same parameter as argument parameter and within handler , .e.g. anyErrors
var dfd = $.Deferred().resolve(true);
dfd.done(function (anyErrors) {
if (anyErrors == true) {
// call ajax routine
return true;
} else {
//stop code execution
return false;
}
})
.then(function (anyErrors) {
if (anyErrors == true) {
// call ajax routine
return true;
} else {
//stop code execution
return false;
}
})
.then(function (anyErrors) {
if (anyErrors == true) {
// call ajax routine
return true;
} else {
//stop code execution
return false;
}
})
.then(function (anyErrors) {
if (anyErrors == true) {
// final code here
document.body.textContent = anyErrors;
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
jsfiddle http://jsfiddle.net/zr5rzb7v/1/

You could use it if you use first then and then done:
var request = $.ajax( url, { dataType: "json" } ),
chained = request.then(function( data ) {
return $.ajax( url2, { data: { user: data.userId } } );
});
chained.done(function( data ) {
// data retrieved from url2 as provided by the first request
});
See official jquery api documentation: http://api.jquery.com/deferred.then/#deferred-then-doneFilter-failFilter-progressFilter

Related

display loading message with ajax

I am trying to display loading message before sending ajax request, and on success callback, hide the message again.
$('#uploadForm').submit( function () {
var fileExists;
if((typeof reference !== 'undefined') && reference) {
$('#loading').css('display', 'block');
CheckFileExists(reference).success(function(response) {
if(response.status === 'true')
fileExists = true;
else if(response.status === 'false')
fileExists = false;
$('#loading').css('display', 'none');
});
if(fileExists) {
alert('Sorry, file already exists!');
return false;
}
}
return true;
});
function CheckFileExists(el)
{
var fi = el; // GET THE FILE INPUT.
if(fi.value !== "") {
var file_name = fi.files[0].name; // FILE NAME
return $.ajax ({
url: "task/file-check",
data: { file_name : file_name},
method: 'POST',
dataType: 'json',
async: false
});
}
}
But this will make the ajax request first, alert pops up, and finally the message appears.
I also tried keeping the if-else inside setTimeout:
$('#uploadForm').submit( function () {
var fileExists;
// load
appendData();
setTimeout(function() {
if((typeof reference !== 'undefined') && reference) {
CheckFileExists(reference).success(function(response) {
if(response.status === 'true')
fileExists = true;
else if(response.status === 'false')
fileExists = false;
$('#overlay-procurement').remove();
});
if(fileExists) {
alert('Sorry, file already exists!');
return false;
}
}
return true;
}, 3000);
});
This will also submit the page (page reloads) while the ajax request is also being made (loader appears and alert pops up).
Also tried beforeSend but found out it doesn't work with async: false.
Do it after submit
$('#uploadForm').submit( function () {
$('#loading').css('display', 'block');
and on success
$('#loading').css('display', 'none');

Long delay before view reflects updated $scope value

In my Angular 1.4.X app, I have some code like this in the controller
function submitForm() {
$scope.submissionInProgress = true;
myService.veryExpensiveOperation();
$scope.submissionInProgress = false;
}
In the view, I try to use $scope.submissionInProgress to show/hide a spinner while veryExpensiveOperation() (a synchronous operation) is in progress.
<div ng-show="submissionInProgress" class="spinner">
Please wait...
</div>
However, what actually happens is that the spinner isn't displayed until veryExpensiveOperation() has almost completed. In other words, it seems there's a delay of a few seconds between when $scope.submissionInProgress = true is called, and when the spinner is actually shown.
Then $http requests are asynchronous. The value of $scope.submissionInProgress gets changed before the request is completed.
If you make an $http request you should better toggle $scope.submissionInProgress inside the resolve function.
e.g.
function submitForm() {
$scope.submissionInProgress = true;
myService.veryExpensiveOperation().then(successCallback, failCallback);
function successCallback() {
//..Do whatever you have to do and then set the $scope on false.
$scope.submissionInProgress = false;
}
function failCallback() {
//Same here
$scope.submissionInProgress = false;
}
}
Solution
I fixed this using $timeout like so:
function submitForm() {
$scope.submissionInProgress = true;
$timeout(function() {
myService.veryExpensiveOperation();
$scope.submissionInProgress = false;
});
}
you can also use callbacks
callback
function submitForm() {
$scope.submissionInProgress = true;
myService.veryExpensiveOperation(function() {
$scope.submissionInProgress = false;
});
}
and the function veryExpensiveOperation:
veryExpensiveOperation = function(callback) {
...
success: function() {
if(typeof callback == "Function") {
callback();
}
}
...
}

Ajax function stops automatically working after a "Failed to load resources" error

I'm using ajax to update some info in my page. I used the $.when $.then functions to identify when the call is over and should activate the timer.
The issue here is that when the call gets a "Failed to load resources" error (no matter which one of them), it will simply stop working at the middle of the execution, and without resetting the timer.
This is the code:
function UpdateCODGW()
{
if(CODGW_Running == false && session_ended == false)
{
CODGW_Running = true;
$.when($.ajax({
url: 'THE_URL',
data: {ajax: 'gwonline'},
type: 'post',
dataType:'json',
success: function(sInfo) {
if(sInfo.session !== false)
{
session_id = sInfo.session;
var gwstatus = $(CODGWID);
sInfo.isonline ? CODGW_Offline = 0 : ++CODGW_Offline;
if(!sInfo.error && sInfo.isonlinestr !== CODGW_Old && (sInfo.isonline || CODGW_Offline >= 3))
{
gwstatus.html(sInfo.isonlinestr);
CODGW_Old = sInfo.isonlinestr;
}
}
else
session_ended = true;
},
failure: function() {
}
})).then(function() { if(session_ended == false) { CODGW_Running = false; UpdateCODGWTimer(); } });
}
}
I don't know what I did wrong that the code won't handle such errors.

Function being used, when it isn't a function?

Battle.CreateInputs = function(json) {
if (json.Battle.Continue !== undefined) {
$('#attackBox').css('display', 'none');
$('#Continue').mousedown(function(e) {
Battle.PlaySound('die')
Battle.Continue($(this).attr('continue'), e);
return false;
});
} else if (json.Battle.Captcha !== undefined) {
$('#attackBox').css('display', 'none');
$('#CaptchaForm').submit(function(e) {
Battle.PlaySound('captcha')
Battle.SubmitCaptcha($('#Captcha').val(), e);
return false;
});
} else if (json.Battle.Restart !== undefined) {
$('#attackBox').css('display', 'none');
$('#Restart').click(function(e) {
Battle.PlaySound('coin')
Battle.Restart($(this).attr('restart'), e);
return false;
});
} else {
$('#attackBox').css('display', 'inline-block');
$('input').mousedown(function(e) {
Battle.PlaySound('hit')
Battle.Move($(this).attr('post_code'), e);
return false;
});
}};
So, this is the code that I'm having problems with. I always receive the error "Battle.PlaySound is not a function". Here is a link to the Javascript and the code snippet that I was using.
My Code - http://pastebin.com/BnHLaYN3
Site Javascript - http://pastebin.com/0NcyWvGn
Battle.PlaySound is indeed not a function. As per your code:
Battle.PlaySound = {};
You are defining it as an object.
Should be something like this instead:
Battle.PlaySound = function(sound) {
//Do something with sound here.
};

How can I stop this setTimeout function from running?

I use the function below to check on the status of a JSON file. It runs every 8 seconds (using setTimeout) to check if the file has changed. Once the JSON's status becomes 'success' I no longer want to keep calling the function. Can someone please show me how to do this? I suspect it involves the use of clearTimeout, but I'm unsure how to implement this.
Cheers!
$(function() {
var checkBookStatus = function() {
var job_id = "#{#job.job_id}";
var msg = $('.msg');
var msgBuilding = $('#msg-building');
var msgQueuing = $('#msg-in-queue');
var msgSuccessful = $('#msg-successful-build');
var msgError = $('#msg-error');
$.ajax({
url: '/jobs/'+job_id+'/status.json',
datatype: 'JSON',
success:function(data){
if (data.status == "failure") {
msg.hide();
msgError.show();
}
else if (data.status == "#{Job.queue}") {
msg.hide();
msgQueuing.show();
}
else if (data.status == "#{Job.building}") {
msg.hide();
msgBuilding.show();
}
else if (data.status == "#{Job.failure}") {
msg.hide();
msgError.show();
}
else if (data.status == "#{Job.success}") {
msg.hide();
msgSuccessful.show();
}
},
}).always(function () {
setTimeout(checkBookStatus, 8000);
});
};
checkBookStatus();
});
t = setTimeout(checkBookStatus, 8000); when you decide to stop the timeout use this clearTimeout(t);.
use clearTimeout
e.g. you defined :
id = setTimeout(checkBookStatus, 8000);
then you can remove this function by :
clearTimeout(id)
Before your call of checkBookStatus() at the end, put another call: var interval = setInterval(checkBookStatus, 8000);. Then on success you can clearInterval(interval).
Do not use setTimeout for iteration.
A lot of answers are suggesting just to use clearTimeout() however, you are checking the status after the timeout has expired, there is no timeout to clear. You need to not call setTimeout() in your always() function rather than to clear anything. So you could re-inspect the status inside your always() function I suppose, but your data object isn't in scope there. It would be preferable to just use setInterval() outside of your checkBookStatus() function.
$(function() {
var checkBookStatus = function() {
var job_id = "#{#job.job_id}";
var msg = $('.msg');
var msgBuilding = $('#msg-building');
var msgQueuing = $('#msg-in-queue');
var msgSuccessful = $('#msg-successful-build');
var msgError = $('#msg-error');
$.ajax({
url: '/jobs/'+job_id+'/status.json',
datatype: 'JSON',
success:function(data){
if (data.status == "failure") {
msg.hide();
msgError.show();
}
else if (data.status == "#{Job.queue}") {
msg.hide();
msgQueuing.show();
}
else if (data.status == "#{Job.building}") {
msg.hide();
msgBuilding.show();
}
else if (data.status == "#{Job.failure}") {
msg.hide();
msgError.show();
}
else if (data.status == "#{Job.success}") {
msg.hide();
msgSuccessful.show();
clearInterval(interval);
}
}
});
};
var interval = setInterval(checkBookStatus, 8000);
checkBookStatus();
});
Call clearTimeout with the value previously returned by setTimeout. This would give you something like:
$(function() {
var timeoutID;
var checkBookStatus = function () {
[…]
else if (data.status == "#{Job.success}") {
clearTimeout(timeoutID);
[…]
}).always(function () {
timeoutID = setTimeout(checkBookStatus, 8000);
[…]
When you use setTimeout, use like this:
var myTime = setTimeout(checkBookStatus, 8000);
to clear it just:
clearTimeout(myTime);
the following should work...
the setTimeout function return an instance of the setTimeout function. Keep this value in a variable and pass it to the function clearTimeout when you want to prevent the event from firing again.
i.e.
var t = setTimeout(1000, someFunction);
...
//after you no longer need the timeout to fire, call
clearTimeout(t);

Categories

Resources