Angular JS – Using Interceptors to handle Http errors

angular.module("myApp.directives", []);
angular.module("myApp.services", []);
angular.module("myApp", [
    "myApp.directives",
    "myApp.services"
])
.config(["$httpProvider", function ($httpProvider) {
    $httpProvider.interceptors.push("myInterceptor");
}]);

//------------
// DIRECTIVES
//------------

angular.module("myApp.directives").directive("myDirective", [function () {
    return {
        restrict: "E",
        replace: true,
        template:
            "<div>" +
                "<h2>myDirective</h2>" +
                "<h3 style='color:red'>{{error}}</h3>" +
            "</div>",
        controller: ["$scope", "myService", function ($scope, myService) {
            $scope.error = null;

            myService.callWorkingApi()
                .then(function () {
                    console.log("myDirective: calling working API success");
                })
                .catch(function () {
                    console.log("myDirective: calling working API failed");
                });

            myService.callBrokenApi()
                .then(function () {
                    console.log("myDirective: calling broken API success");
                })
                .catch(function () {
                    console.log("myDirective: calling broken API failed");
                });

            //Here we are catching up the
            //event raised by the interceptor
            $scope.$on("http-error", function (event, args) {
                $scope.error = args.status;
            });
        }]
    };
}]);

//----------
// SERVICES
//----------

angular.module("myApp.services").service("myService",
    ["$http", '$q', function ($http, $q) {
        var _self = this;

        _self.callWorkingApi = function () {
            return $q(function (resolve, reject) {
                $http.get("/json/data.json")
                    .then(function (result) {
                        resolve(result.data);
                    })
                    .catch(function (error) {
                        reject(error);
                    });
            });
        };

        _self.callBrokenApi = function () {
            return $q(function (resolve, reject) {
                $http.get("/json/wrong.json")
                    .then(function (result) {
                        resolve(result.data);
                    })
                    .catch(function (error) {
                        reject(error);
                    });
            });
        };
    }]);

//-----------
// FACTORIES
//-----------

angular.module("myApp").factory("myInterceptor",
    ["$q", "$rootScope", function ($q, $rootScope) {
        return {
            "response": function (response) {
                return response || $q.when(response);
            },
            "responseError": function (response) {
                if (!!response && !!response.config) {

                    //Here we can perform different
                    //actions based on the error code
                    console.log("myInterceptor:", response.config.url,
                        response.status, response.statusText);

                    //Here we are broadcasting an event
                    //for another directive to catch up and
                    //handle (to display a popup for instance)
                    $rootScope.$broadcast("http-error", response);
                }
                return $q.reject(response);
            }
        };
    }]);

And here is the output:

Leave a comment