$location.path doesn't change in a factory with AngularJS
Asked Answered
W

4

5

My factory looks like:

'use strict';

angular.module('myApp')
  .factory('httpInterceptor',['$q','$location', '$rootScope', function($q, $location, $rootScope){
    return {
      response: function(response) {

        if(response.success === false) {
console.log("Redirecting");
            $location.path('/login');
            return $q.reject(response);
        }

        return response || $q.when(response);
      }
    }
}]);

It spits out the log, but doesn't change the path. What can I do to make this happen?

Waltz answered 21/10, 2013 at 15:59 Comment(1)
Related question: #25580438Able
H
10

The documentation for $location says:

Note that the setters don't update window.location immediately. Instead, the $location service is aware of the scope life-cycle and coalesces multiple $location mutations into one "commit" to the window.location object during the scope $digest phase.

Hence, if the rejection of the promise has an effect on $location, then you may not see the intended change.

To force a change outside of the angular life-cycle, you can set the hash using window.location and then force a reload of the page. This will, of course, stop execution of any code which follows and erase the session, but that might be what you want if the user is not logged in.

Hypoblast answered 2/11, 2013 at 1:36 Comment(1)
I found it very frustrating to not be able to get various angular solutions to redirection working, and having to resort to window.location for my redirection.Artwork
B
6

There are certain cases where $location will not redirect if it is outside angular's apply cycle. Try wrapping the $location inside the $apply.

$rootScope.$apply( function(){$location.path('/somelocatin'); } );
Berryman answered 2/11, 2013 at 1:55 Comment(2)
are you cheating Angular?Rikkiriksdag
is there a risk using this method? I used it - and it worked. can this affect the application state?Lailalain
E
3

This one worked for me on Angular 1.3.14

myServices.factory('Factory', ['$rootScope', '$location', function ($rootScope, $location) {
  // do something and redirect
  $location.path('path')
  $rootScope.$apply()
}])

Notice that the $rootScope.$apply() is after the $location.path('path') call, for some reason wrapping it inside the $apply call callback as suggested above wasn't working.

Extort answered 11/3, 2015 at 8:45 Comment(0)
J
0

Try

$location.path('#/login');

instead of

$location.path('/login');
Jarietta answered 1/11, 2013 at 2:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.