Why Angular.js promise is better than callbacks in javascript - angularjs

We are using Angular JS promises heavily and its one of the recommend practice from Angular team also. I feel that its just a syntax sugar on the top of Callback. But not sure about it. Can anybody give me few examples where Angular.js promises are better than javascript callbaks?

Promises can be chained and avoid the 'pyramid of doom'. They also have a defined way of handling results like success and failures, which with callbacks is not the case.

if you have multiple ajax calls and on each success of those calls sometimes you have to call the same ajax method again. Coding such scenario becomes ugly with callbacks.
Promise handles that very elegantly.

Related

Does AngularJS promise scheduling work with `async`/`await`?

TypeScript constantly suggests that I change my AngularJS service code to async/await functions.
My understanding is that using the await keyword is totally fine with third-party promises, since it is just syntax sugar for calling then. However, I normally return Angular promises because they are necessary to play nicely with the digest cycle.
This code gives me an error because async functions wrap their contents in an ES6 promise. Will this matter for Angular scheduling, given that the returned promise is still hooked up to an Angular-spawned promise? Or should I submit an issue to TypeScript for suggesting async/await when functions do not explicitly return an ES6 promise?
For anyone viewing this in the future. It does not play nicely. async functions wrap their contents in a global ES6 promise, so if you await AngularJS promises within the changes will eventually hit, but scheduling is weird when you chain together $q promises and ES6 promises, so there will usually be an artificial delay before changes are reflected in the DOM.
On the other hand, Angular 2+ monkey-patches DOM event sources and promises, so async-await should work as expected with newer versions.

Angular Http - toPromise or subscribe

I have watch a few courses on Angular and have found there are different ways to manage data from an Http request.
Using Observables, .map(), .subscribe()
Using Promises, .toPromise(), .then(), .catch()
I have used toPromise() in my application as I find it similar to the AngularJS Http services.
In what scenario would I need to use Observables?
If you like the reactive programming style and want to be consistent within your application to always use observables even for single events (instead of streams of events) then use observables. If that doesn't matter to you, then use toPromise().
One advantage of observables is, that you can cancel the request.
See also Angular - Promise vs Observable
I think as long as the response is not a data stream that you're going to use, then you'd better use the .toPromise() approach, because it's meaningless to keep listening to a response that you don't need and it's not even going to change.
UPDATE
.toPromise() is now deprecated in RxJS 7, they replaced it with something better firstValueFrom and lastValueFrom.
So your code should look like this:
await lastValueFrom(httpRequest$)
For more info about this check these links:
https://rxjs.dev/deprecations/to-promise
https://www.youtube.com/watch?v=3aeK5SfWBSU
Default http requests in angular emits observables. It can be converted to promise by calling toPromise(). But it is not required. Angular unsubscribes the http request once it gets resolved by calling
`_xhr.removeEventListener('load', onLoad);
_xhr.removeEventListener('error', onError);
_xhr.abort();`
Observables are cancellable, but promises are not.
The open request remain even after the component gets destroyed leading to memory leakage, which can be prevented by unsubscribing the observable or calling the destroy method once the component gets destroyed. Ways to unsubscribe to prevent memory leaks
Conclusion, better to use observables with memory leak prevention techniques.

Which URL to use when working with $httpBackend expectGET

When expecting a call to the API should I include the entire URL including all the parameters, or do I just need a partial match?
Should I be listening for a call to the exact URL :
http://address.of.api/stuff/123?include=thing,anotherthing.name;
Or do I just need this :
/stuff/123
$httpBackend is part of Angular's Mock environment designed to replace real backend by fake one, or rather by imitating how Angular's $http works without real backend.
As much as I love Angular, I find $httpBackend over-engineered and unnecessarily complicated for what it does:
It is not recommended way to throw complicated code inside your tests. The more you do it, the more chance is that you create errors in that testing code instead of what you are actually supposed to test.
It promotes the bad practice of placing $http (or other low-level services in your abstraction hierarchy) freely around your code, as you can later use that $httpBackend to mock it away.
Instead it works cleaner to isolate any reference to low level methods into dedicated methods of your own, whose single responsibility is to make http requests. These dedicated methods should be able to work with real backend, not a fake one!
More details here on Angular testing

AngularJs console.log "$q is not defined"

I am getting this error in the console $q is not defined. When I did some research I found some thing like .q library has been deprecated from
http://www.breezejs.com/documentation/breeze-labs/breezeangularqjs
If this is so, then the whole concept of promises is also deprecated,
Promises are not deprecated. In fact they're gaining quite a lot of momentum lately and are included in the next version of JavaScript.
Let's look at what they say:
This breeze.angular.q library has been deprecated. It is superseded by the Breeze Angular Service which more cleanly configures breeze for Angular development.
The Breeze Angular Service tells Breeze to use Angular's $q for promises and to use Angular's $http for ajax calls.
What they say is that breeze uses Angular's own promises for promises rather than its own breeze.angular.q which uses Q promises which are more able but also much heavier than $q promises which Angular uses. This is simply an API change.
Inside Angular code, you can obtain $q using dependency injection - for example with the simple syntax:
myApp.controller("MyCtrl",function($q){
//$q is available here
});
Alternatively, if you want to use it independently you can use service location and obtain $q directly from an injector, but that's rarely the case. (If you want an example - let me know, I'd just rather not include code that's usually indicative of bad practice).
# in your console, try following code
$injector = angular.injector(['ng']);
q = $injector.get('$q');
deferred = q.defer();
# then do whatever you want

angularjs solution for async $scope $apply

So I know if the call is outside angularjs or it is async then we need $apply to update the
angularjs scope.
What is the best practices to using $apply if I have many api/3rd party in my app?
I always forgot or didn't know that api/plugin is async.
I would write a wrapper service for each lib that needs it, and encapsulate callbacks in angular promises, but remember it's only neccessary for asynchronous functions, if you call a synchronous external lib, this should work as expected without issues.

Resources