Which is better .success() or .then() in angular - javascript

I am making an ajax call to server to fetch some data.
$.ajax(
{
url: "myserver",
method: "GET",
}.success(function(data)
{ }
.error(function(e)
{ }
)
I have been reading about .then().
Is there any performance benefit of using .then() over .success()?
Is there any particular scenario where I should use .then() and .success()?
Plus, whoever answers,please brief me in short What is Promises.

You should be using then as the success and error have been deprecated.
https://docs.angularjs.org/api/ng/service/$http
The $http legacy promise methods success and error have been
deprecated. Use the standard then method instead. If
$httpProvider.useLegacyPromiseExtensions is set to false then these
methods will throw $http/legacy error.

.then( ) call returns a promise while .success( ) is more traditional way of registering callbacks and it doesn't return a promise.
Moreover .then() is commonly used where you need to chain promises whereas .success() method is a streamlined, convenience method when you don't need to chain call nor work with the promise API.

I would recommend using .then() and .catch(). Those methods are in line with the CommonJS standard. As you use other Promise libraries, it's more likely that they'll use those two methods.
I would also avoid using the .then(successCallback, failureCallback) approach, as it is not standard and less obvious.

This is a great article which helps you to understand Promise
http://andyshora.com/promises-angularjs-explained-as-cartoon.html
and
The major difference between the 2 is that .then() call returns a promise (resolved with a value returned from a callback) while .success() is more traditional way of registering callbacks and doesn't return a promise.

I personally prefer .then(), here is a very good blog on why .success() is not preferred.
For an API call I would do something like this:
$http.get('www.domain.com/someAPI').then(function (results) {
// On successful promise
doSomethingHere();
}, function (error) {
// On failed promise
handleError();
});

.Success and .then both work same but there are lot of difference between there response unit, In angular and ajax success work same after evening thing goes completed and you might need to fetch response data then User .success,
In .then it happens before .Success and After .Success.
so if You have Loading bar in your html code use before success .then for loading...
and after success use .then for hiding it.

Related

jquery - usage of .done(), .then() and .when() for making ajax requests in a given order

I've been doing a lot of reading about Promises in jquery and avoiding "callback hell" when making multiple ajax requests.
I feel though even after reading all this, there's no simple answer being given to what to use - in terms of .done(), .then() and .when() - in terms of chaining the requests.
I've tried to construct the most basic example to illustrate my point. The code below works exactly as I want it to, but the only thing this relies on is .done() and I can't see where other methods (such as .then() or .when()) fit into this.
So I have created 3 PHP scripts and used PHP's sleep method to artificially delay how long these scripts take to complete. The delays are set as follows:
r1.php - 5 seconds
r2.php - 1 second
r3.php - 3 seconds
The script itself is as simple as this:
<?php
// r1.php
echo "starting r1.php \n";
sleep(5); // Delay execution. Varies as described above for each script
echo "ending r1.php \n";
?>
So if these were run in parallel, the order they'd complete in would be r2.php, r3.php, then r1.php.
But what if we wanted to run them in order (r1.php, r2.php, r3.php) and have jquery wait until each ajax request was made before going on to the next? For example if something in r2.php depends on the result of r1.php etc.
I've written the following - which does exactly that:
$(document).ready(function() {
$.ajax({
url: 'ajax/r1.php',
method: 'get'
}).done(function(response1) {
console.log('After r1.php\n');
console.log(response1);
$.ajax({
url: 'ajax/r2.php',
method: 'get'
}).done(function(response2) {
console.log('After r2.php\n');
console.log('response1:' + response1);
console.log(response2);
$.ajax({
url: 'ajax/r3.php',
method: 'get'
}).done(function(response3) {
console.log('After r3.php\n');
console.log('response1:' + response1);
console.log('response2:' + response2);
console.log(response3);
});
});
});
});
As you can see, the requests are completing in order, and taking the time specified in each PHP script:
Furthermore, due to the scope in which the callbacks are running I can access, for example, response1 (the output of r1.php) in the callback that handles r3.php:
My question is: Under what circumstances are any functions other than .done() (such as .then() or .when() - which are mentioned in countless resources) actually needed to do this type of thing? When would you even need .then() or .when() for this type of scenario?
As far as I understand, .done() is Promise-compatible. I've even replaced .done() with .then() in the code above and the results are exactly the same.
I have read all of the following but I feel like all of these are complicating the issue, of how to run ajax requests in order with jquery:
jQuery deferreds and promises - .then() vs .done()
How do I chain three asynchronous calls using jQuery promises?
https://medium.com/coding-design/writing-better-ajax-8ee4a7fb95f
Please can someone explain this in a way beginners can understand? I am using jquery 3.2.1 so would like a response that's specific to jquery, not vanilla JavaScript.
I originally asked this question but I feel it was badly worded and didn't include enough code. So I've mocked up the code given here to illustrate the exact problem.
The .done() method is only called when the Promise resolves (as opposed to .fail(), which is called when the Promise is rejected).
The .then() method accepts a resolved and a rejected callback and is equivalent to using done/fail together, such that:
$.ajax().then(resolvedCallback(), rejectedCallback());
Is equivalent to
$.ajax().done(sucess()).fail(failure());
The difference being that multiple .then() can more easily be chained together for more complicated Promise resolution.
The .when() method allows you to encapsulate some logic in a Promise/Deffered/Thenable so that you can use .then(), .done(), and .fail() can be used. This is useful if you have some complex or long running logic you want to execute and need to wrap it in a Promise/Deferred easily. It also make it easier to read:
$.when(function(){/*I do something that takes a while*/})
.then(function(){/*I succeed*/},
function(){/*I fail*/})
.then( ... )
.then( ... )
...
You can then end the chain in an .always() to clean up any sort of result or perform some action that must always happen at the end of your chain, regardless of whether or not your promises resolved or were rejected.
Edit: Putting It All Together
Using .when(), we can have code wait unit a number of things are complete before proceeding:
function fetchMe(url) {
return $.ajax({
url: url,
method: 'get'
});
}
$.when(fetchMe('ajax/r1.php'), fetchMe('ajax/r2.php'), fetchMe('ajax/r3.php'))
.then(function(r1, r2, r3) { // Resolve
console.log('response1: ' + r1.data);
console.log('response2: ' + r2.data);
console.log('response3: ' + r3.data);
}, function(){ // Reject!
console.log('Something broke!');
});
In this example, fetchMe() returns the Promise from the $.ajax() call. Using .when(), we tell the script to wait for all three of these to complete before proceeding to the .then(). The input of the resolve method takes deferred items in the order they are in the .when() and, from there, we can retrieve the data from the request.
You can try $.Deffered to chain multiple ajax calls to make them sequential.
Docs:https://api.jquery.com/category/deferred-object/
Similar issue: How to make all AJAX calls sequential?

angularjs simple .then or $q service in async requests

I don't know what is the exactly difference between AngularJS $q service and simply using .then() after async request.
Simple example with .then() :
function InboxService($http) {
this.getEmails = function getEmails() {
return $http.get('/emails');
};
}
And when using the service (just part of code):
InboxService.getEmails()
.then(function (response) {
// use response
});
What is the difference with $q service with resolve and reject ?
What is the difference with $q service with resolve and reject ?
I assume you are asking about the usage of var deferred = $q.defer() with subsequent deferred.resolve() or deferred.reject()? In this case, the answer is that you don't need it since you already have a promise object returned by $http service. In fact, manually constructing another new promise with $q is not recommended and considered an anti-pattern.
In cases where you work with asynchronous functions (timeouts, ajax-requests) that are not already wrapped into promise, then this is a case when you might want to use $q to create and return promise. But once again, in your case you don't need it as $http service constructs promise for you and one more is simply redundant.
The $q is superfluous and in most cases is not needed. http://www.codelord.net/2015/09/24/$q-dot-defer-youre-doing-it-wrong/

Hood.ie - Data not found using find

Just started to use Hood.ie for a web app, however am facing issues in obtaining some data.
I want to get the data and then simply do something like
hoodie.store.find('teammember', theId).firstName;
Is this possible?
Thanks.
What you are looking for is
hoodie.store.find('teammember', theId)
.done(function(object) { object.firstName })
.fail(function(error) { alert(error.message) })
Most methods of Hoodie are asynchronous and return promises. A promise is an object with methods to which you can pass callback function. By standard, a Promise has .then & .catch methods, Hoodie also adds .done & .fail. .done(callback) gets called when the method succeeded. .fail(callback) gets called when it failed. .then(callback) and .catch(callback) additionally allow to chain the callbacks.
Find more information on Promises here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise And a great article on common gotchas here: http://pouchdb.com/2015/05/18/we-have-a-problem-with-promises.html

Promisifying an API

If I want to promisify all code paths in myFunction, do I need to create a deferred inside myFunction?
function myFunction(options) {
if(!options) {
throw 'foo'; // But I want the API for myFunction to be promise-based...
}
return promiseBasedApi.doSomethingAndReturnPromise();
}
do I need to create a deferred inside myFunction?
(That's jQuery terminology, the general case would be "Do I need to create a promise in my function?")
Only if your function doesn't already have a promise it can return; frequently, it does, if it's waiting on any asynchronous operation (ajax, some other promise-based API, etc.) to complete.
if(!options) {
throw 'foo'; // But I want the API for myFunction to be promise-based...
}
If you're asking if you need to create an reject a promise for the error that options is not provided, no, I wouldn't expect that of an API. There are two aspects to an asynchronous operation's API:
Initiation
Completion
In the above, failing to supply options is an error during the initiation of the request. I would expect an inline exception, not an asynchronous error callback.
Errors processing the request (HTTP failures, etc.) would be errors I'd expect via the promise's rejection mechanism.
No, you do not need a deferred or the Promise constructor in your function. You do need those only for non-promise-based APIs. Even then, you should not use it globally, but a separate promise capability for each asynchronous code path.
In your case, you should just return a rejected promise instead of throwing:
function myFunction(options) {
if (!options) {
return Promise.reject(new FooError()); // as promised!
}
return promiseBasedApi.doSomethingAndReturnPromise();
}
An alternative, if you are using Bluebird, would be to wrap your throwing-or-(promise)-returning function in Promise.method. See also Should an async API ever throw synchronously? and Should a Promise.reject message be wrapped in Error? for related discussions.

Returning angular promise from a function that resolves the promise very quickly

I am writing an asynchronous javascript function that will be called by consumers to get certain data. Following is the simple implementation that I wrote initially (error handing and other stuff removed for clarity).
function getData(callback){
if (data is available as a JavaScript object){
callback(data);
}else{
getAsyncData(function(data){
//some transformations on data
callback(data);
});
}
}
What is important to note is that getData can return data quickly if data is already available as a JavaScript object.
I want to replace this implementation with the one that returns a promise object to the caller. This fiddle shows sample implementation - http://fiddle.jshell.net/ZjUg3/44/
The question - Since getData can return quickly, can there be a possiblity where getData is resolving the promise even before caller has established handler chain using then method? Just to simulate this, in the fiddle if i call then method inside setTimeout function (with zero delay), callback doesn't get called. If i call the then method outside of the setTimeout function, callback gets called. I am not sure if this is even a valid concern or valid usecase. I am quite new to angularjs development and would appreciate your views :)
If you want getData() to return a $q promise instead of using a callback, I'd do the following refactor using $q.when() and usual $q.resolve():
function getData()
{
if (data is available as a JavaScript object) {
return $q.when(data); // resolves immediately
} else {
var q = $q.defer();
getAsyncData(function(data){
//some transformations on data
q.resolve(data);
});
return q.promise;
}
}
No, a significant and important part of being a promise is that it doesn't matter when you attach the handler. Even if you create a promise now and resolve it immediately, then keep your computer running for the next 50 years, then attach a handler it will still fire.
All of this does assume that there isn't a bug/corner case in angularjs's promise implementation. If it doesn't work, it's a bug though.
If you ever need to know anything about how promises work, you can always refer to the Promises/A+ spec which angular adheers to. As a spec, it's one of the simplest and easiest to understand that I've come across (although I should mention that I've been involved in the spec for quite a while now).

Categories

Resources