4

I'm doing some basic routing with ngRoute. I define a service that uses $http and plug that into resolve. Normally I explicitly use $q in the service, but this time I'm using the built in .then and .catch, and it's not working like it normally does. Here's a pared down version of what I've got:

app.config(["$routeProvider", "$locationProvider", 
    function($routeProvider, $locationProvider){
        $locationProvider.html5Mode(false);

        $routeProvider
            .when("/", {
                templateUrl: "views/index.html",
                controller: "indexCtrl",
                resolve: {
                    myData: function(myService){
                        return myService.getMyData();
                    }
                }
            })

            .otherwise({
                templateUrl: "views/404.html"
            });
    }]);

The service:

app.factory("myService", ["$http", "$route", function($http, $route){
    return {
        getMyData: function(){
            return $http.get("www.url.com")
                .then(function(data){
                    return data;
                })
                .catch(function(err){
                    return {err: "There was an error"};
                })
        }
    }
}]);

And the controller where the error is handled:

app.controller("errorCtrl", ["$rootScope", function($rootScope){

    $rootScope.$on("$routeChangeError", function(event, current, previous, rejection){
        console.log("err", rejection);
    })

}]);

And in the view:

<body ng-app="App" ng-controller="errorCtrl" ng-view>

The problem is that the value returned by catch() is not being passed to the rejection parameter of the routeChangeError handler. I would normally pass the data with deferred.reject(data), but I'm at a loss as to why .catch() doesn't work the same way. In fact, the .catch block doesn't seem to be getting hit at all. If I go into the service and try to break something, this triggers the routeChangeError handler in the controller, but not the catch block. Just wondering if someone can provide some insight into what's going on here?

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
branweb
  • 171
  • 7

1 Answers1

3

If you return from the catch, you have handled the error, and the resulting promise will get fulfilled. See also Chained promises not passing on rejection.

You will need to re-throw an error (or return a rejected promise) if you want a rejection:

getMyData: function(){
    return $http.get("www.url.com")
    .catch(function(err){
        throw new Error("There was an error");
    })
}

(I've also removed the useless .then(identity))

Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375