ui-router deferIntercept and state params

All we need is an easy explanation of the problem, so here it is.

I use the new deferIntercept() of ui-router to update the browser url without reloading
my controller:

$rootScope.$on('$locationChangeSuccess', function(e, newUrl, oldUrl) {
  e.preventDefault();
  if ($state.current.name !== 'search') {
    $urlRouter.sync();
  }
  $urlRouter.listen();
});

With this code, a click on the browser’s back button changes the URL to the previous one, but I’m not able to update my controller state to mirror this change.
$stateParams still contains the values set when the user first loaded the page.

What’s the best way to update the $state and $stateParams objects inside my controller when the user click the back button or change the URL manually ?

thanks !

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

Your call to $urlRouter.listen() should be placed outside the event handler. The code snippet you provided should be changed to:

$rootScope.$on('$locationChangeSuccess', function(e, newUrl, oldUrl) {
  e.preventDefault();
  if ($state.current.name !== 'search') {
    $urlRouter.sync();
  }
});

// Moved out of listener function
$urlRouter.listen();

Source: The official documentation for $urlRouter provides a code sample for the deferIntercept method. It places the call to $urlRouter.listen() outside of the listener function:

var app = angular.module('app', ['ui.router.router']);

app.config(function ($urlRouterProvider) {

  // Prevent $urlRouter from automatically intercepting URL changes;
  // this allows you to configure custom behavior in between
  // location changes and route synchronization:
  $urlRouterProvider.deferIntercept();

}).run(function ($rootScope, $urlRouter, UserService) {

  $rootScope.$on('$locationChangeSuccess', function(e) {
    // UserService is an example service for managing user state
    if (UserService.isLoggedIn()) return;

    // Prevent $urlRouter's default handler from firing
    e.preventDefault();

    UserService.handleLogin().then(function() {
      // Once the user has logged in, sync the current URL
      // to the router:
      $urlRouter.sync();
    });
  });

  // Configures $urlRouter's listener *after* your custom listener
  $urlRouter.listen();
});

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply