handling $http.get and $http.post errors in Angularjs - angularjs

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);
});
}
});

Related

retry HTTP request without using factory

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.

Sending a promise from one controller to another in Angular

In my web app, I would like to load all of the user data at the beginning, in the run method and pass the data to the other controllers to be shown to the user in the dashboard.
So lets say I have a data structure on the server
data = {
x : 30,
y: 20
}
I would like to get it in one http requests (instead of creating multiple http requests and creating multiple promises)
The http request I run in the run method of the app
service.getDataFromServer = function(){
return $http.get('/admin/data').then(function(response) {
data = response.data;
});
};
This will create a promise.
I would like to take this promise and pass it to other controllers to be used.
My first question is how can I do it so the data from the promise will bind to the data I am about to show to the user.
The second question is, can I use the structure fields before the promise is even resolved?
for example
$scope.x = data.x
And by data I mean the data which is about to be resolved
Thanks
I would like to get it in one http requests (instead of creating multiple http requests and creating multiple promises)
After getting response from http call,save the data in factory/services so,you can use is at another location like controller in your case by injecting it which is most recommended.
I would like to take this promise and pass it to other controllers to be used.
how can I do it so the data from the promise will bind to the data I am about to show to the user.
make http call and save the promise.
service.getDataFromServer = function() {
var promise = $http.get('test.json');
service.savePromise(promise);
}
and
get saved promise.
.controller('testCtrl', function(service) {
service.getSavedPromise().then(function(response){
console.log(response.data)
})
})
Plunker here
The second question is, can I use the structure fields before the promise is even resolved? for example
$scope.x = data.x
// data is still undefined as promise is not resolved.so,you will get TypeError
What you can do best here,you can merge data to your existing data object/array,so,Angular two way binding can do rest of the things for you.

Always do action before and after $http

I want my app to always do some actions before and after $http running like loading animation or delete all messages.
// Add loading animation + Remove all messages
$http({}).then(function(response) {
// Remove loading animation + Add Success messages
}, function(response) {
// Remove loading animation + Add Failure mesages
});
But if I code like this, my code is not DRY.
How can I do this without repeat myself?
Thank you!
You should be able to implement it with Interceptors. Read the below one.
http://www.webdeveasy.com/interceptors-in-angularjs-and-useful-examples/
You can inject your custom service into the Interceptor component. In the request function enable animation ON and turn it OFF in the response function. Your home page should also use the same service to have an animated DIV with an ng-if like
<div ng-if="vm.myHttpStateService.isBusy">
..... animation here ...
</div>
Use the promise's .finally method
//Add loading animation + Remove all messages
$http({}).finally(function() {
//Remove loading animation
}).then(function onSuccess(response){
//Add Success messages
}).catch(function onReject(response){
//Add Failure mesages
});
From the Docs:
The Promise API
Methods
finally(callback, notifyCallback) – allows you to observe either the fulfillment or rejection of a promise, but to do so without modifying the final value. This is useful to release resources or do some clean-up that needs to be done whether the promise was rejected or resolved. See the full specification for more information.
-- AngularJS $q Service API Reference -- The Promise API

How do I get http response in Restangular .then() function from Laravel Request validation

Okay, I'm using Restangular and Laravel 5.1, and I need to be able to handle failed form validation. One way would be to do it on the front end with Angular, but I'd also like to be able to handle it server side.
Currently, the request reaches my form request, and then the form request returns
{"users":["The users field is required."]}
In my Angular controller, I have the following:
Factory.update(var1, var2).then(function(results) {
console.log("results");
});
This doesn't return anything because it's never reaching that point. Laravel kicks it out before then.
Thoughts?
I don't know Laravel, but I know how HTTP should work.
Seems like Laravel is sending back an HTTP status code for error (anything above 400 is an error).
Restangular detects this status code, and then it'll reject that promise, instead of resolving it -- that's why your console.log call is never reached.
You should do the following instead:
Factory.update(var1, var2).then(function(results) {
console.log("results");
}, function(error) {
console.log("oh you got errorz!");
});

can we resolve any deferred with any response in angularjs

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.

Resources