Is there a way to retry a http call when it rejected, without using factory?
I thought of making a custom service and send it the http method, url and callbacks functions. but I would like to know if there is better way to do this.
Thank you.
You can wrap the $http call in a function and call that function from within the resulting promise's error callback:
function makeHttpRequest(){
$http.post("your-url-goes-here")
.then(successCallback, errorCallback);
function successCallback(obj){
// do something...
}
function errorCallback(err){
makeHttpRequest();
}
}
There is obviously huge potential for an infinite loop using this approach and you would be wise to restrict the number of retry attempts.
Related
I stuck with ashync call chain. I tried google but couldn't found exact answer.
requirement is I have a method
callApi(){
I am calling 4 service that all are asynchronous.
I want to chain all the asynchronous calls so that I can do
defer.resolve only when all request are done
}
Any help would be great help.
Thanks in Advance.
You can just use $q.all(). It takes an array of promises and returns a promise, that will resolve when all promises in that array have resolved.
Example:
function callMultipleServices() {
return $q.all([
//Just some random functions returning promises...
someAsyncService(),
$http.get('http://google.de'),
someOtherAsyncService()
]) //.then(function(resultArray) { return doSomethingWith(resultArray) })
}
The returned promise will resolve with an array, containing the resolved values of the promises you passed in. If you want your promise to return a single value that is somehow derived from the service results, just add a .then that takes the results and somehow calculates your final promise result (as in the comment above)
I had an issue with and angular-meteor project flickering every time a state using the campaigns subscription, would load. By flickering, I mean the data was there, then it would go away and come back a half second later.
I added this to the resolve property of the state (using ui-router):
campaigns: ($q) => {
var deferred = $q.defer();
Meteor.subscribe('campaigns', {
onReady: deferred.resolve,
onStop: deferred.reject
});
return deferred.promise;
}
The flickering stopped, but I don't really understand this code. Can someone who understand angular break this resolve/defer situation down?
Just not sure why it worked. thanks.
$q is angular's implementation of promises.
in a very itty bitty nutshell, a promise has two callbacks that resolve when data is returned; a resolve function if the call succeeds and a reject if the call fails. whatever data it gets will be passed into these functions (essentially doing deferred.resolve(data) or deferred.reject(error)) . $q.defer() allows us to assign the resolution/rejections later.
meteor's subscribe function takes a few arguments. the string name of the collection, a function that returns an array of arguments to be passed to the collection, and an object/function. the object part of the final argument expects an "onReady" and "onStop" functions, and will execute those functions and pass along any data it gets. we pass in our callbacks here.
finally, we return the promise. resolve.campaigns will be a promise, which we can get the values from using the .then(successCallback, failureCallback) call. meteor handles this behind the scenes.
I have 2 questions -
1) What is the difference between the "success" and "then"?
example - $http.get(url).then vs $http.get(url).success?
2) A promise means something that would be executed in the future, fine. I am not able to wrap my head on how this is difference from a function call. a promise call is executed when we make call using "$q.defer.resolve()". Isn't this a function call? so why can't this be a normal function, and executed with any other function call like foo()? Am i missing something special that a promise does!! ?
What is the difference between the "success" and "then"?
then() takes a single argument: the http response object. success() takes 4 arguments: the data of the response, the status of the response, the headers of the response, and the http config object. success() is thus easier to use when all you care about is the data returned. As said by New Dev, the returned value is different: then() returns a new promise for whatever is returned from its callback and allows you to return a new value and thus build a promise chain, whereas success() returns the original promise.
A promise means something that would be executed in the future
No, not really. A promise is the result of something you execute now, but for which the result is not immediately available. Since JavaScript is single-threaded, you can't just block and wait for the result, because that would completely freeze the application. So you just register a callback function that will be called, asynchronously, when the result is available. For example:
$http.get('/some/url')
immediately sends an HTTP request. But to get the result, we need to wait for the bytes to travel to the server, for the server to handle the request and send back a response, and for the response to travel to the browser. This could take several seconds. So what $http.get() returns immediately is a promise: i.e. an object which represents a future result (or, once the result has been received, a result that was once future).
.then returns a new promise.
.success returns the original promise. Another difference is that .success gets the response.data as an input parameter, whereas .then gets the response.
This is how it's implemented:
promise.success = function(fn) {
promise.then(function(response) {
fn(response.data, response.status, response.headers, config);
});
return promise;
};
You could use .success (and .error) to handle the respective outcome of $http, but without the ability to modify the data or to reject a promise (with return $q.reject()) given to the eventual consumer of the $http promise.
Here's an illustrative example of when one may use .success vs/with .then:
return {
getData: function(p1){
return $http.get(url, {p1: p1})
.success($log.log) // can use generic functions since there is
.error($log.error) // no requirement to return data
.then(function(response){
// here can massage the data into the output format
return response.data;
});
};
I recommend always using .then since it returns a new promise without .success and .error handlers; this avoids the chance of the API consumer using the $http-specific .success/.error thus inadvertently making the assumption that $http was used under the covers.
Folks,
I am using $http.get and $http.post all over my code. I am kind of lost as to how to handle errors that occur during these calls in a global fashion.
Currently I have .success(doSomething).error(doSomething) on every call.
I would like to change this and instead simply display the error on top of my page.
I read about using interceptors with myapp.something. But I absolutely do not understand how to implement this.
Kindly assist
Response interceptors are attached during the config phase of an angularjs app. You can use them to globally respond to any $http request. Be aware, template files also use $http request, so you may wish to filter some requests in your interceptor to only the ones you wish to respond to.
A good understanding of the promises pattern is needed to successfully use response interceptors.
Heres an example of how they are used:
angular.module('services')
.config(function($httpProvider){
//Here we're adding our interceptor.
$httpProvider.responseInterceptors.push('globalInterceptor');
})
//Here we define our interceptor
.factory('globalInterceptor', function($q){
//When the interceptor runs, it is passed a promise object
return function(promise){
//In an interceptor, we return another promise created by the .then function.
return promise.then(function(response){
//Do your code here if the response was successful
//Always be sure to return a response for your application code to react to as well
return response;
}, function(response){
//Do your error handling code here if the response was unsuccessful
//Be sure to return a reject if you cannot recover from the error somehow.
//This way, the consumer of the $http request will know its an error as well
return $q.reject(response);
});
}
});
I cant understand, certain things in this code http://www.espeo.pl/2012/02/26/authentication-in-angularjs-application
This code, this trying to resend same request(the one user requests before logging in) after the user logs in.
My question
Inside the retry function, they are resloving a deffered with the
response of a request that is sent after the user logs in. The
response and the deffered are no way related to each other. Why they
should do this?
-
function retry(req) {
$http(req.config).then(function(response) {
req.deferred.resolve(response);
});
}
Please have a look at the code in the above url for understanding how the retry method works.
You can resolve a promise with whatever you want. In this case, a promise was returned to the application when the 401 status code/error was first encountered. Now, after the loginConfirmed event, the request is sent again and the response is used to resolve that promise.