Angular Http Priority - angularjs

I am making lots of API calls in my applications i.e say 50.
The total time for completing all the api calls will be around 1 minute. The priority for all the api calls will 2. I have enabled the angular cache.
So in meantime if the user of my applications just want to focus on the some of the api calls among the all i.e say just 6 api calls.
Then once again I will project that 6 api calls with priority 1 .
But still I dont get what I aimed ? i.e these 6 api calls need to receive the data asap.
Kindly refer the below example code .
On Initial load :
for(var i=1,priority=19;i<=19,priority>=1;i++,priority--)
{
$http.get("http://localhost:65291/WebService1.asmx/HelloWorld"+i+"?test=hari",{priority:2})
.then(function(response) { });
}
}
On some event click :
$http.get("http://localhost:65291/WebService1.asmx/HelloWorld7?test=hari",{priority:1})
.then(function(response) { });
}

if you want send multiple http request one shot then use $q.all
Inside the loop push the http requests to an array and send that http array at once.
var httpArr = []
for (var i = 1, priority = 19; i <= 19, priority >= 1; i++, priority--) {
httpArr.push($http.get("http://localhost:65291/WebService1.asmx/HelloWorld" + i + "?test=hari", {
priority: 2
}))
}
$q.all(httpArr).then(function(response) {
console.log(response[0].data) //1st request response
console.log(response[1].data) //2nd request response
console.log(response[2].data) //3rd request response
})

Related

How to stop double request to same url

Angularjs app here.
There are 2 controllers that do similar things.
In particular, they have an interval. Each 10 seconds they go to their own service.
These 2 different services also do similar things. Most important is that they go to an URL that looks like this:
example.com/fromTimestamp=2019-11-21T15:13:51.618Z
As the two controllers start more or less at the same time, in the example above they could generate something like:
controller/service 1: example.com/fromTimestamp=2019-11-21T15:13:51.618Z
controller/service 2: example.com/fromTimestamp=2019-11-21T15:13:52.898Z
This is because the parameter is created in the service with his line:
var timestamp = fromTimestamp ? '&fromTimestamp=' +fromTimestamp.toISOString() : '';
So maybe there will be a difference of some seconds. Or even only a difference of milliseconds.
I would like to make only one request, and share the data fetched from http between the two services.
The most natural approach would seem to be using cache.
What I could understand is that this call could make the trick:
return $http.get('example.com/fromTimestamp=2019-11-21T15:13:51.618Z', {cache: true});
But looking in the dev tools it is still making 2 requests to the server. I guess this is because they have 2 different urls?
If that is the problem, what could be another approach to this problem?
In my apps, when face with this problem, I use the $q provider and a promise object to suspend all calls to the same endpoint while a singleton promise is unresolved.
So, if the app makes two calls very close together, the second call will not be attempted until the promise created by the first call is resolved. Further, I check the parameters of the calls, and if they are the same, then the original promise object is returned for both requests. In your case, your parameters are always different because of the time stamp. In that case, you could compare the difference in time between the two calls, and if it is under a certain threshold in miliseconds, you can just return that first promise object. Something like this:
var promiseKeeper; //singleton variable in service
function(endpointName, dataAsJson) {
if (
angular.isDefined(promiseKeeper[endpointName].promise) &&
/*promiseKeeper[endpointName].dataAsJson == dataAsJson && */
lastRequestTime - currentRequestTime < 500
) {
return promiseKeeper[endpointName].promise;
} else {
deferred = $q.defer();
postRequest = $http.post(apiUrl, payload);
postRequest
.then(function(response) {
promiseKeeper[endpointName] = {};
if (params.special) {
deferred.resolve(response);
} else {
deferred.resolve(response.data.result);
}
})
.catch(function(errorResponse) {
promiseKeeper[endpointName] = {};
console.error("Error making API request");
deferred.reject(extractError(errorResponse));
});
promiseKeeper[endpointName].promise = deferred.promise;
promiseKeeper[endpointName].dataAsJson = dataAsJson;
return deferred.promise;
}
}

How to make request every 2 seconds with angular js and node js?

I have a server written with Nodejs that collects data. My client side is written with AngularJS. I need to create http request every two seconds to my server (setInterval) and display updated data. My server running 24/7. Can chrome block my requests if it reaches maximum? Can I implement another way, instead of create request from client side, maybe to push from my server?
Example of some request:
var indicesTimer = setInterval(getIndices,2000);
getIndices();
function getIndices(){
dataService.getIndices().then(function(res){
$scope.recentIndeces = res.data;
});
}
Check $interval service.
var stop = $interval(function() {
// Your code
}, 100);
With your code
var indicesTimer = $interval(getIndices,2000);
getIndices();
function getIndices(){
dataService.getIndices().then(function(res){
$scope.recentIndeces = res.data;
});
}
You can use websocket. By using that, your server can notify your client in case something changed in the server side so you don't have to do a polling (polling is what you do when sending request every x seconds). Take a look at socket.io
This is the typically behavior of a heartbeat. Chrome or any other browser does not block requests.
As long as your setInterval() handler doesn't run forever, it won't block other things from eventually running.

how to check multiple responses simultanously

$scope.placeOrder = function() {
var callbackBalance = apiService.updateBalance($scope.order);
callbackBalance.then(function(data) {
if(data.data.success) {
var callback = apiService.createOrder($scope.order);
callback.then(function(data){
if(data.data.success)
{
localStorageService.cookie.clearAll();
alert("Order Placed Successfully");
$state.go("createOrder");
}
else
alert('Sorry! Cannot place order');
});
}
else
{
alert('Cannot update company balance')
}
});
This a code to place order for a company and update its balance amount according to the order total.The code works fine but according to this code first the balance amount API is called and once its response is success order API will be called and its response will be checked.But, how can we check if both are successful then only update databases for balance and order.Right now a case can be that balance is updated for a company but for some reason no order was placed.
I am using MEAN stack for my development.
You can use $q service from angular
A service that helps you run functions asynchronously, and use their
return values (or exceptions) when they are done processing. You can
create a request object like this
You can create request array and pass it to $a.all function.
var request = [apiService.updateBalance($scope.order), apiService.createOrder($scope.order)]
and use $q.all function to get provided request simultaneously
$q.all(request).then(function (response) {
}, function (error) {
});
that will get the request data simultaneously. Make sure to add $q as dependency.

Not sending sms on loop with cordova plugin

I am trying to send sms on loop with Cordova plugin.
The issue that big part of SMS not sent.
Dose cordova have some limitation or should I do some ideal time?
this my code:
var contactsLen = $scope.contacts.length;
for (var i = 0; i < contactsLen; i++) {
if ($scope.contacts[i].hasOwnProperty('number')) {
$cordovaSms
.send($scope.contacts[i].number, text)
.then(function () {
if (i == contactsLen - 1) {
$scope.log += 'send All!'
}
}, function (error) {
The plugin code that sends the SMS is asynchronous, which means running it in a loop like that will not work the way you expect. If you want to fire multiple async events and wait for them all to finish, then you need to use something like q$ (https://docs.angularjs.org/api/ng/service/$q) to handle it. Make note of the all() method which lets you pass an array of promises.

Don't execute a $resource request in angular when there is already a request running

I use a interval of 10 seconds for sending a request to get the most recent data:
var pollInterval = 10000;
var poll;
poll= $interval(function()
{
getNewestData();//$resource factory to get server data
}, pollInterval );
This works fine voor 99% of the time, but if the internet speed is really slow(I have actually experienced this), It will send the next request before the current is finished. Is there a way to just skip the current interval request if the previous one is still busy? Obsiously I could just use booleans to keep the state of the request, but I wonder if there is a better(native to angular) way of doing this?
Use the $resolved property of the Resource object to check if the previous operation is done.
From the Docs:
The Resource instances and collections have these additional properties:
$promise: the promise of the original server interaction that created this instance or collection.
$resolved: true after first server interaction is completed (either with success or rejection), false before that. Knowing if the Resource has been resolved is useful in data-binding.
$cancelRequest: If there is a cancellable, pending request related to the instance or collection, calling this method will abort the request.
-- AngularJS ngResource $resource API Reference.
How about making the request, then waiting for that to complete and then wait 10 seconds before making the same request again? Something along this line:
var pollInterval = 10000;
var getNewestData = function () {
// returns data in promise using $http, $resource or some other way
};
var getNewestDataContinuously = function () {
getNewestData().then(function (data) {
// do something with the data
$timeout(function () {
getNewestDataContinuously();
}, pollInterval);
});
};
getNewestData is the function that actually makes the request and returns the data in a promise.
And once data is fetched, a $timeout is started with timer as 10 seconds which then repeats the process.

Resources