2

In my angular app I need to read some data from the server before I allow the rest of my application to run. For example, I need the user authenticated so I can verify their permission before I allow them access to anything. Since I need to do this on app start and I don't know what controller will be loaded first, I can't use the resolve feature of the $routeProvider.when method because I do not know which controller will be hit first, and it only occurs once on app start.

I keep steering towards doing something in the module.run method, but I can't find a way to prevent it from continuing until get the data back from the server. I found this but it suffers from the same problem: AngularJS : Initialize service with asynchronous data.

I can also do manual bootstrapping, but I can't find any good examples of how to do this. Any help you can provide would be appreciated.

2 Answers 2

1

The easiest way i can think of here would be to have a separate page for login. Once the user is authenticated then only allow him access to the main app (angular app).

Also you need to secure you service resources against unauthorized request. This would safeguard against your controller \ views loading unauthorized data.

Sign up to request clarification or add additional context in comments.

Comments

1

Like the other answer already mentioned, you should take care of the security of your app.

Possible solutions are:

Check if the user is authenticated

Implement a authentication in your API. You can check if the user is logged in with a responseInterceptor:

.config(['$routeProvider','$httpProvider', function($routeProvider,$httpProvider) {

  //setup your routes here...   

  var authChecker = ['$location', '$q', function($location, $q) {
      //redirects the user to /login page if he's not authorized (401)
      function success(response) {
          return response;
      }

      function error(response) {

          if(response.status === 401) {
              $location.path('/login');
              return $q.reject(response);
          }
          else {
              return $q.reject(response);
          }
      }

      return function(promise) {
          return promise.then(success, error);
      }
  }];

  $httpProvider.responseInterceptors.push(authChecker);
}])

See $http docs for more details.

Workaround: run scope

Does not solve the security issues, but is working, too:

Get your data in the run block like this:

.run(function($http,$location,$rootScope) {
    $rootScope.$on("$routeChangeStart", function (event, next, current) {
        if($rootScope.gotData) {
             $location.path(next.path);
        } else {
            $location.path('/loading');
        }
    });

    $http.get('path/to/data').success(function() {
        $rootScope.gotData = true;
        $location.path('/home');
    }).error(function() {
        $location.path('/404');
    })
})

see docs for further information.

2 Comments

Is there a way to hold up the app loading while waiting for the get to return?
Sure. For example, you could use a simple boolean which is set "true" in the success block of your request. Then, you can listen to $routeChangeStart in your run-block. If the boolean is false, you can redirect the user to a loading page.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.