3

Resolve is an interesting property to prevent a template to be displayed regarding some conditional logic dealing with a promise result (solved or rejected).

I use it in my application, here's a conceptual sample:

.config(['$routeProvider', 'securityAuthorizationProvider',
        function ($routeProvider, securityAuthorizationProvider) {
              $routeProvider.when('/test', {
                  templateUrl: '/myCorrespondingView.tpl.html',
                  controller: 'MyCorrespondingCtrl',
                  resolve: securityAuthorizationProvider.requireAuthenticatedUser
              });
        }])

So, this code expects to display /myCorrespondingView.tpl.html content if and only if securityAuthorizationProvider.requireAuthenticatedUser is resolved (promise term).

My expectation is: I don't want to change the URL to http://myApp.com/test if this promise in resolve part is rejected. The reason is simple, I don't want to uselessly reload the previous controller if my rejection logic is to let the user on his current page (thus needing a redirection to this latter) .

Is there an efficient way to achieve this with the resolve property other than shifting the conditional logic at the source, meaning into the previous controller?

Mik378
  • 21,881
  • 15
  • 82
  • 180
  • The docs are saying: " If any of the promises are rejected the $routeChangeError event is fired" Quote from another question: Note that you can globally listen for routing events through: $rootScope.$on('$routeChangeStart', callback), also works for $routeChangeSuccess, '$routeChangeError'. Useful is you want to display a loader, progress bar and handle errors. – Did i get something wrong? – Wottensprels Oct 29 '13 at 10:08
  • @Sprottenwels But the URL change happens though. Imagine the user on the current page: /index.html. Then he clicks on "A protected page" link on the menu. As he's not logged, an authentication popup is opening requiring user entries (opening throws by `resolve`). At this time of opening, the URL is already marked as: /a-protected-page.html. So if the user wants to give up authentication, the popup closes, but a redirection to /index.html is necessary...uselessly, although he's already there. If I deal with `$rootScope.$on`, I'd have to repeat this logic in many controllers. – Mik378 Oct 29 '13 at 10:13
  • Maybe this could help you: http://egghead.io/lessons/angularjs-resolve-routechangeerror i can't watch it by myself right now, therefore i have no idea if that guy has a solution for your "i'll have to do it in every controller" problem. good luck – Wottensprels Oct 29 '13 at 10:18
  • @Sprottenwels Thanks for the link. It allowed me to configure a listener deciding to redirect page or not regarding the promise result of the `resolve` of the targeted protected page. However, in the case when I choose to not redirect (meaning if a `previous` controller exists), the page doesn't redirect so (well :)), but when I click again on the protected link, nothing happened => as if Angular checks: "if you try to `resolve` a page, but you are already in there, I don't want to `resolve`!" and thus, my popup doesn't show again. Any idea to solve the last issue? Thanks again. – Mik378 Oct 29 '13 at 12:38
  • Unfortunately not, sorry. I'll do some research later, though. Will comment here if i found something helpful. – Wottensprels Oct 29 '13 at 15:19
  • @Sprottenwels Thanks :) I wrote a dedicated post to this "issue": http://stackoverflow.com/questions/19659183/angularjs-forcing-resolve-property-to-run-at-anytime Maybe be better to post the comment there if you have any :) – Mik378 Oct 29 '13 at 15:47

2 Answers2

0

I was dealing a similar problem some time ago. My solution was to redirect the user to a login page - you can use the page user is coming from - in the authentication provider (in your case it would be securityAuthorizationProvider.requireAuthenticatedUser) if the user wasn't logged in.

lithin
  • 1
0

I know this is an old question, but for all users who are looking for an answer, i will provide my solution.

I have a popup / modal / alert whatever which is displayed over the whole page. in this popup is a history, so you can open a new view and can go back to the old view.
I added a feature that you can go back with your back-button on mouse or browser.

my js:

SYSTEM.run( [ "$rootScope", "Popup", function( $rootScope, Popup ) {
    $rootScope.$on( "$routeChangeStart", function ( e ) {
        if ( $rootScope.popup ) {
            Popup.back();
            e.preventDefault();
            return;
        }
    } );
} );

So what you could do is, get the next route (provided in $routeChangeStart) and check if this url is secured and run your service. if your service is resolved redirect to the url and set the checking variable to true/false, so on the next change you won't check your service again.

Hope that helped.

Mephiztopheles
  • 2,228
  • 1
  • 12
  • 25