Angular JS $http promise object -- How does it work? - angularjs

All,
I'm a beginner to Angular framework and have been reading $http service. I thought I understood Promise object in Angular JS until the below questions popped up my mind. Can you please help me understand?
– When I make a REST call from Angular, Angular work not make the rest call before it executes the other steps in the js from where the REST API is invoked. This is because it’s single threaded. Okay I get this. So when does it execute the REST call? May be after all the instructions in the current JS are done? If yes,
Why do we even call it asynchronous?
Secondly, during the time it executes the REST API (let’s say the REST API results in an output not before 2 seconds), right after it calls REST API would Angular just wait for the 2 seconds without doing anything?
If $http service executes the REST API asynchronously as soon as it sees it,
Who spawns the second thread to execute the REST API? The framework? If so then are they making Javascript no longer be uni–threaded?
Secondly when the service returns while the main thread hasn’t even completed executing all the lines in my js, does Angular/jQuery goes and executes the instructions coded in the .then function, leaving the instructions in the main thread waiting?
Thanks much for your help!
Prem

When I make a REST call from Angular, Angular work not make the rest call before it executes the other steps in the js from where the REST API is invoked
No. That is incorrect. It sends the request immediately. But it doesn't block until the response comes back, because that could take a whole lot of time and completely freezes the application. So instead, it registers a callback, and this callback will be called, later, when the response is available. That's the principle of asynchronism.
Who spawns the second thread to execute the REST API
There is no second thread.
The easiest way to look at it is to consider that an HTTP response is an event, just like a click or a keypress. All the unique thread does is to wait for the next event and react to it, in a loop.

First of all, it wont block the execution, it sends the request immediately. Basically it follow the promise pattern which uses the concept of callback function. So whenever API returns the response it calls the callback function and resume the process.
There is no concept like second thread. When HTTP return the response the execution doesn't stop. it just call its callback method and after that excute the remaining line of code

Related

Protractor - waiting for async to finish

In our application we are calling every minute to our feature flags service using angular therefore browser.waitForAngular() always fail.
is there a way to use browser.waitForAngular() and make it ignore this specific feature flag call (API call that is being called every 60 secs) so we can still use the wait for angular and not implement waits on the code?
There is an option to enable/disable waitForAngular which may be used to disable for pages where polling is happening and enabled again later for other pages..Check the below link
browser.waitForAngularEnabled

Force protractor to wait for seed data to load

I have to load some seed data for my tests. I'm having a really hard time making sure the seed data has loaded completely before the tests begin running.
In the beforeAll block I'm calling an adapter I wrote for my API that clears out any data, loads a specified file of seed data and then runs a callback passed in from the protractor test file.
I can't include the test cases in a callback (this seems like it would be a similar blocking issue to refactoring to promises) or protractor doesn't recognize them.
Can anyone suggest a way I can make sure my API has been successfully seeded before the tests begin?
Thanks!
If you are using Jasmine 2.1 or higher with Protractor you can make use of the done() function in your beforeAll.
So if you have a function called seedMyDataAsync() that takes a callback function as a parameter, you could do something as simple as this:
beforeAll( function(done) {
seedMyDataAsync(done);
});
The done() function was introduced with Jasmine 2.0, but wasn't available for beforeAll() until Jasmine 2.1.
From the documentation:
Calls to beforeAll, afterAll, beforeEach, afterEach, and it can take an optional single argument that should be called when the async work is complete.
By default jasmine will wait for 5 seconds for an asynchronous spec to finish before causing a timeout failure. If the timeout expires before done is called, the current spec will be marked as failed and suite execution will continue as if done was called.

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!

How to skips model dirty checking with $http?

You can skip model dirty checking in $timeout service by setting the third parameter called invokeApply to false (see documentation).
Is it possible to achieve the same result with the $http service?
I need to call a legacy third-party restful webservice several times, but must reduce the amount of refreshes on the UI...
No, but you can use jQuery.ajax or any other ajax library to make http requests out of the digest loop.
In fact, $http will not send any request outside the digest loop. This is from the angular comments:
The $http service will not actually send the request until the next $digest() is
executed. Normally this is not an issue, since almost all the time your call to $http will
be from within a $apply() block.
If you are calling $http from outside Angular, then you should wrap it in a call to
$apply to cause a $digest to occur and also to handle errors in the block correctly.

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