I've ended up doing this:

First of all, I have added a route called '/loading'; when 
locationChangeSuccess detects the condition, it saves the path being 
accessed and redirects to /loading:

          else if (!nextRoute.access.isPublic) {
            // redirect to login form
            if (this.authStatus === 'loading') {
                this.loadingPath = nextRoutePath
                $location.path('/loading')             
            } else if (this.authStatus != 'seemsLoggedIn')

This view simply displays a 'loading' logo to the user, while waiting for 
the XHR to complete. To detect the completion and switch back to target 
view that the user intended to see I $broadcast an event when the status is 
fetched:

    $http.post(url, data).success(function(data, status) {
      self.authStatus = data.authStatus
      $rootScope.$broadcast('APP_STATE')
    })

In the top-level controller of my SPA, I react to this event by restoring 
the original view that the user wanted to see:

            $scope.$on('APP_STATE', function() {
              var targetPath = appState.loadingPath
              if (targetPath != null) {
                appState.loadingPath = null
                $location.path(targetPath)
              }
            });

I am not sure this is the most elegant solution, but in any case it works 
and also prevents excessive "flicker" of the screen while switching from 
one view to another.


On Friday, 28 March 2014 20:16:35 UTC, Alexandros Karypidis wrote:
>
> Hi,
>
> I find myself in this predicament:
>
> The short version of the question is "is it possible to pause execution 
> until an XHR completes" ?
>
> My app has a service that tracks the user status. When it loads, the 
> service issues a $http call to the server, to fetch the status (logged in 
> if a session exists, not logged in otherwise. Something like (simplified) 
> this:
>
>     var appstateSvc = {
>         authStatus: null,
>
>          refreshAuthStatus: function() {
>     //...
>     $http.post(url, data).success(function(data, status) {
>        //...
>       self.authStatus = data.authStatus
>     })
> },
>
> I also have a locationChangeSuccess handler registered which verifies the 
> user is logged in when arriving at a location. It inject the above service 
> and in cases where the target location would be "log-in" only I redirect to 
> a login view:
>
>           else if (!nextRoute.access.isPublic) {
>             // redirect to login form
>             if (this.authStatus != 'seemsLoggedIn')
>              this.interceptForLogin(nextRoutePath);
>
>
> This works fine for the most part, but has the following problem:
>
> 1. Assume I am logged in looking at my SPA
> 2. I close the browser tab
> 3. I open a new tab before session times out (still logged in) 
> 4. I select a bookmark to some location that requires log in
>
> What happens at this point is that the $http call has not returned yet and 
> the status is "loading". However, my location change handler gets called 
> and redirects to the login page. How can I prevent this from happening?
>
>           else if (!nextRoute.access.isPublic) {
>             // redirect to login form
>             if (this.authStatus === 'loading') {
>                         // HERE what can I do?
>                         // I know XHR is in progres and need to wait for
>                         // respones...
>             } else if (this.authStatus != 'seemsLoggedIn')
>              ...
>
> Thank you!
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"AngularJS" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/angular.
For more options, visit https://groups.google.com/d/optout.

Reply via email to