0

So... I'm trying to learn some Angular stuff and then I reached a point where I'm stuck. In my app I'm using third party APIs so I cannot rely on $http, that's why you'll see $apply in the code.

So, basically I have this:

.when('/dashboard',{
  controller : 'DashboardController',
  templateUrl : 'ui/modules/dashboard/dashboard.html',
  resolve : {
    data : function(myService){
      return myService.start();
    }
  }
})

So far nothing really strange. That method supposedly have a promise, right? The start function is as follows:

var start = function(){
  return initializeConnection().then(function(){
    return login(false);
  });
};

So, basically, if everything works, all works. That's great. The thing is that, if I get promise rejection on the second function (that's login) I'm not able catch the error in this, which is my AppController which is created on top of the app (so it's always being instantiated):

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

That's basically never called. A solution I tried that works, is to return a promise from the start function, then if any of those async functions fails, fail the returned promise. But as I see it, it should be unnecesary.

Can you point me in the right direction?

Antonio Laguna
  • 8,973
  • 7
  • 36
  • 72

1 Answers1

0

In your code, if you get promise rejection the DashboardController is never instantiated and your view is never loaded - so not much you can do there. You need to have a controller that will be instantiated even if your promise is rejected.

I think you could create a controller just to handle global events like $routeChangeError. I've created one below called checkConnection and it will be assigned to the root element of the app .

var myApp = angular.module('myApp', []);

myApp.config(function($routeProvider){
  $routeProvider
    .when('/dashboard',{
      controller : 'DashboardController',
      templateUrl : 'ui/modules/dashboard/dashboard.html',
      resolve : {
        data : function(myService){
          return myService.start();
        }
      }
    })
});


myApp.controller('checkConnection', function ($rootScope){
    $rootScope.$on("$routeChangeError", function (event, previous, current, rejection) {
      console.log('Failing');
    });
});

myApp.controller('DashboardController', function($rootScope) {
    // code for your controller goes here
});

And in your index.html you will have:

<div ng-app="myApp" ng-controller="checkConnection">
    <ng-view></ng-view>
</div>

The controller checkConnection is going to be instantiated anyway - so you can rely on that to handle the error.

If no error happens then the specific controller (e.g: DashboardController) for the route you are accessing will be executed normally and your view will be loaded.

There are room for improvements but I think that could work for you.

Hope that helps or at least point you to the right direction.

Denison Luz
  • 3,575
  • 23
  • 25
  • Hi dluz, I forgot to mention that... I already have that code in AppController. Updating question – Antonio Laguna Sep 04 '13 at 19:43
  • Hi Antonio, I did investigate it further and tried to replicate the issue you were having. Please take a look at this [link](http://stackoverflow.com/a/18661324/1310945). It has 2 nested promises and if any of these promises fails the controllers still handles it. – Denison Luz Sep 06 '13 at 15:34