Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS - Should we wrap $http methods in a service

Tags:

angularjs

My question is that given the power of interceptors, does it make sense to wrap $http in a service so that all my other code just calls that wrapper. Now basic tasks like header/exception handling can easily be done by interceptors. So though I cant think of a valid usecase now, but lets say just to shield any future api changes etc to $http? Or maybe later migrate to $resource?

Also please note that here I am talking of a basic wrapper service around $http’s methods, not a client service like DataService with methods sendData, receiveData that wraps $http calls. Please find below sample code -

angular.module(‘myapp’).factory(‘myhttpwrapper’, ['$http', function (http) {
  return {

    myGet: function (getUrl) {
      return http.get(getUrl);
    },
    myPost: function (postUrl, data) {
      return http.post(postUrl, data);
    },
    // other $http wrappers
  };
}]);

Now all other code will use myhttpwrapper’s myGet, myPost methods instead of $http’s get, post methods. Hope it makes sense!

[EDIT] What use-cases we'll definitely have is to intercept requests for adding headers, logging, and responses for logging, exception handling, etc. But I am sure these can be handled by interceptors. Later moving from $http to $resource is not known at this point.

Thanks.

like image 237
user3231682 Avatar asked Jan 25 '14 13:01

user3231682


People also ask

What is $HTTP in AngularJS?

$http is an AngularJS service for reading data from remote servers.

How do you modify the $HTTP request default Behaviour?

To add or overwrite these defaults, simply add or remove a property from these configuration objects. To add headers for an HTTP method other than POST or PUT, simply add a new object with the lowercased HTTP method name as the key, e.g. $httpProvider. defaults.

Which of the following is the correct syntax for making a get call and handling the error in angular?

get(url) . then(function (response) { console. log('get',response) }) . catch(function (data) { // Handle error here });

How do we pass data and get data using http in angular?

Use the HttpClient.get() method to fetch data from a server. The asynchronous method sends an HTTP request, and returns an Observable that emits the requested data when the response is received. The return type varies based on the observe and responseType values that you pass to the call.


2 Answers

For the specific case you describe, I'd advise against wrapping $http. There is no real gain in doing it.

A case where this could come into play would be where you'd want a more 'speaking' API. Lets say you have User(s) in a system, and Address(es). You described it as a data based service DataService:

var app = angular.module("users", []);

app.service("User", ['$http', '$q', function(http, q) {
  return {
    getAddress: function(user) {
      var address = q.defer();
      http.get("/user/" + user.id + "/address").then(function(data) {
        address.resolve(data);
      }, function(err) {
        address.reject(err);
      });
      return address.promise;
    },
    getUser: function() {
      var user = = q.defer();
      http.get("/user/address").then(function(data) {
        user.resolve(data);
      }, function(err) {
        user.reject(err);
      });
      return user.promise;
    }
  }
}]);

This allows you to use parameters for your call. Whenever you'd have to change routes, you would have only one place to change them (this would be really awful if, say, you had a dozen controllers making $http requests).

You can also make use of $resource here if you which (and you actually have compatible resources). The decision making factor(s) here should be readability, reusability and ease of change later.

So, if you only ever have on place where you make these calls and the routes never change, go ahead and use the $http directly, without a wrapper. This I'd consider unlikely in a growing application.

like image 109
Florian Avatar answered Oct 11 '22 17:10

Florian


I needed my 'get' generalized so did it like this:

app.factory('myHttp', ['$http', '$q', function($http, $q) {
return {
    get: function(url) {
        var deferred =  $q.defer();
        $http.get(url).then(
            function(response) {
                //console.log("response good");
                deferred.resolve(response)
            },
            function(response) {
                //console.log("response bad");
                deferred.reject(response)
            })
        return deferred.promise;
    }
};
}]);

You can now chain an additional "then" to the result of the get. You can have core logic for handling error or success (my use case being to log out the user if credentials expired) but still allow for additional context specific logic for the get response (like setting $scope etc...).

like image 27
SilentDirge Avatar answered Oct 11 '22 17:10

SilentDirge