Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Verifying route preconditions prior to loading controller

I'm writing a single page application in Angular, specifically angular.dart, but I'm assuming this question still applies to AngularJS.

Take for example the following routes:

/login - Expects nobody to be logged in. If someone is authenticated but not registered, redirect to "register" route, if they are registered, redirect to the "home" route.

/register - Expects an authenticated user who hasn't finished the registration process. If not authenticated, redirect to login. If is authenticated, redirect to home.

/home - Expects an authenticated and registered user. If not authenticated, redirect to "login" route, if not registered, redirect to "register" route.

I've done quite a bit of searching but cannot find a built-in or idiomatic way to check to make sure that certain preconditions are met before loading the controller associated with a particular route, and to redirect appropriately when these preconditions are not met.

Any help would be greatly appreciated!

like image 784
w.brian Avatar asked Dec 06 '13 17:12

w.brian


2 Answers

Angular.Dart and Angular.JS routing frameworks are very/fundamentally different. Angular.Dart is using a third party routing framework (https://github.com/dart-lang/route/tree/experimental_hierarchical) and only implements angular specific features like ng-view and ways to bind routes to templates via ViewFactory.

So your question really falls into the route_hierarchical package domain. Currently you can veto users attempt to navigate away from a route, but I guess what you want the ability to veto user entering a route depending on if the user is logged in or not. Unfortunately this is not yet supported, but is planned.

What you could try in the meantime is creating a custom viewFactory wrapper.

class RecipesRouteInitializer implements RouteInitializer {
   void init(Router router, ViewFactory view) {
     router
       ..addRoute(
          name: 'login',
          path: '/login',
          enter: authView(router, view('login.html'), NOT_AUTH))
       ..addRoute(
          name: 'register',
          path: '/register',
          enter: authView(router, view('register.html'), AUTH_NO_REG))
       ..addRoute(
          name: 'home',
          path: '/home',
          enter: authView(router, view('home.html'), AUTH_AND_REG));
   }

   authView(Router router, ngView, mode) {
     return (RouteEvent e) {
       if (mode == AUTH_AND_REG) {
         if (!authService.isAuth) {
           router.go('login', {});
           return;
         }
         if (!authService.isReg) {
           router.go('register', {});
           return;
         }
       } else if (mode == AUTH_NO_REG) {
         if (!authService.isAuth) {
           router.go('login', {});
           return;
         }
         if (authService.isReg) {
           router.go('home', {});
           return;
         }
       } else if (mode == NOT_AUTH) {
         if (authService.isAuth) {
           router.go('register', {});
           return;
         }
       }
       ngView(e);
     };
   }

}

DISCLAMER: this is just an idea... might totally not work.

like image 116
pavelgj Avatar answered Nov 15 '22 17:11

pavelgj


Well, I made a thing in Dart which is close to one of the previous solutions which don't really work. The main point is that in the RouteEventHandler, you need to call the RouteEventHandler of the view.

      ..addRoute(
          name: 'userAdd',
          path: '/userAdd',
          enter: checkAuthentication(router,view,'view/addUser.html'))
      ..addRoute(
        name: 'login',
        path: '/login',
        enter: view('view/login.html'));
  }

  RouteEventHandler checkAuthentication(Router router,ViewFactory view, String location){
     return (RouteEvent e) {
      if(_authenticationService.isAuthenticated()){
        view(location)(e);
      }else{
        router.go("login",{});
      }
    };
  }
like image 23
user3300744 Avatar answered Nov 15 '22 16:11

user3300744