Angular Http - toPromise or subscribe - angularjs

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.

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.

Why Angular.js promise is better than callbacks in javascript

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.

angularjs $http with cache and interceptor

I'm trying to use angulars $http, with both a cache and an interceptor.
The quick question:
Currently when angular gets the answer from the server, it first caches it, and then it passes it through the interceptor.
Is it possible to force angular to first pass it through the interceptor and only then cache it?
The long issue:
The server responds every call with a format similar to:
{permission: BOOL, data:[...]}
In the interceptor response I check the permission, and if correct I throw it away and pass only the data field to the application level. If it fails I reject and popup an error, etc... (Maybe I should do it in a transformResponse function, but I'll endup facing the same issue).
Then for some API calls I'm requesting a bunch of resources like that:
/resource/ALL
And it obviously caches this request and answer, but what I want to do next is fake caching every resource that I received.
So forthcoming calls to /resource/{some resource id} are already cached, cause I've already received it in the call where I requested ALL.
The problem I'm facing is, when I want to fake cache, on the application level, I lost the "{permission: BOOL" part, cause I've thrown it in the interceptor.
Some notes:
1- Of course I could also fake the permission part, and just hardcode it, but I feel it's not an option since if I later add / modify / remove metadata it's another place I've to look at.
2- An other way would be to don't throw the metadata on the interceptor / transformResponse, but again this is not an option since I don't want to select the 'data' field every time I call $http on the application level.
So I think the best option for me would be to cache after the interceptor, and not before.
Hope I made the issue clear, and any answer is welcome!

Batch update, create and delete the REST way

Using Tastypie and AngularJS $resource I would like to perform a set of update, create and delete operations.
Currently, I broadcast an event:
$rootScope.$broadcast('save');
That event is captured by each controller responsible for creating, updating and deleting using the $resource service:
ResourceService.update({id:$scope.id}, $scope.element).$promise.then(function(element) {
$scope.$emit('saved');
});
Now, this cause some race conditions both at client side and on server side.
What would be the simplest way to perform this set of operations as a batch in the REST way?
I recently played around with Angular HTTP Batcher
however if you want a more generic JS only async helper you can use Async
I think those are mostly what you are looking for, the blog post from the Angular HTTP Batcher is a good read.

Best practice for angular service

I have a simple question about best practices.
A service loads once at load time.
Let's say there is a method called getUser in the service called user.
I have to call getUser in several controllers.
The GET request will happen twice right?
Is there a good practice to check whether the data has already been fetched to avoid this second call?
Yes, the call gets executed twice. You can use angular's built in $http cache option, or you could use an existing module like angular-cache, or other libraries such as Breeze or Amplify. You can also try handling it yourself, probably the worst option.

Resources