0

I'm writing a single-page application in AngularJS that needs to know, whether user is logged-in before running any routes at all.

I'm using Django backend, which supports anonymous sessions, so just looking at cookies I can't figure, if user is logged-in or anonymous. So, to find that out I want to make an Ajax request to backend in Angular application-global .run() and delay any execution of angular application until that request finishes.

How do I do that?

Boris Burkov
  • 13,420
  • 17
  • 74
  • 109
  • 1
    I would suggest you use https://github.com/angular-ui/ui-router/wiki#resolve in ui-router or an http interceptor https://docs.angularjs.org/api/ng/service/$http. – Abdul Mannan Mar 28 '16 at 09:47
  • For your need, you should use ui-router resolve. But its better to check for the server response with an http interceptor and redirecting the user if authentication fails. – Abdul Mannan Mar 28 '16 at 09:49
  • @AbdulMannan I considered using ui-router's `resolve` as a last resort solution. Unfortunately, with this approach I'd have to manually call the same `resolve` code at every route, which is repetitive and error-prone. Checking out `$http` interceptors. Thanks for suggestion. – Boris Burkov Mar 28 '16 at 09:50
  • 1
    In that case, you should use interceptors and in case of failed authentication, return a 403 error from server and look for the 403 error resonse in your angular interceptor and redirect. – Abdul Mannan Mar 28 '16 at 09:53
  • @AbdulMannan Probably, you are right. Reading the docs currently. Just one question: will interceptors delay rendering of the first page until authentication promise is resolved? Cause I want to avoid the scenario when an anonymous page starts rendering and then in the middle of that a promise resolves, so user gets a Frankenstein of anonymous and logged-in pages. – Boris Burkov Mar 28 '16 at 09:58
  • Actually interceptors work on the request/response of the server and meanwhile your template will be loaded, so i suggest using ng-cloak on that page and it might help with your scenario. – Abdul Mannan Mar 28 '16 at 10:02
  • Route resolvers should be first resort solution and not last, that's what they are for. There are abstract routes in UI Router to keep it DRY, and even if they are inapplicable, it can be treated [like that](http://stackoverflow.com/a/33895051/3731501). – Estus Flask Mar 28 '16 at 10:44
  • if you have session cookie and user cookie, then you can say the different. – YOU Mar 28 '16 at 10:51
  • @estus aha, abstract route might be a good solution indeed! And that's even logical, not a hack, cause the abstract route describes the navbar structure, which requires authentication. Thanks! – Boris Burkov Mar 28 '16 at 10:54
  • @estus As suggested in question, you pointed to, more radical approach will be to use `$on($stateChangeStart)` in `run()` block. Probably, that's exactly what I was looking for. – Boris Burkov Mar 28 '16 at 11:00
  • You're welcome. And $stateChangeError allows to handle auth errors with ease. – Estus Flask Mar 28 '16 at 11:11

1 Answers1

0

Create a directive that you can put on each view. Our project has a base view using razor so it makes it easier. Let the directive wait for the promise and only make the content visible when it is resolved.

Daniel van Heerden
  • 836
  • 1
  • 7
  • 25