Search code examples
angularjsangularng-upgrade

Angular Router not updating browser URL when called from AngularJS


I have an AngularJS application, which I'm in the process of converting to a hybrid Angular/AngularJS application using ngUpgrade. The AngularJS application is unusual in that it doesn't use the AngularJS or Angular UI router - instead it has its own hand-rolled navigation solution, which doesn't update the URL displayed in the browser, or interact with the browser's history API. So far, so good.

I want to start using the Angular Router in the hybrid application, but initially only for new pages.

To get the 2 parts of the application - Angular and AngularJS - interoperating with each other, I have downgraded the Angular Router service and injected it into one of my AngularJS services, so that I can call Router.navigateByUrl() to navigate to a new Angular page component, from my AngularJS code.

This works correctly - the Angular page component is added to my <router-outlet> and is displayed in the browser as expected.

Strangely though, the browser URL does not change. When I enable tracing for the Router, I can see the new route being correctly processed, and the new page is displayed in the browser, but the browser URL still shows the old route. Also, if I look at the browser history, the new route has not been added to it.

I've tried injecting NgZone into my AngularJS service and calling Router.navigateByUrl() inside NgZone.run(), but it doesn't make any difference.

When I call Router.navigateByUrl() from my Angular code, everything works fine - except when I do this after I've done it from AngularJS, when I then see the same symptoms. It's as if calling the Router directly from AngularJS is somehow breaking the link between the route and the browser URL bar.

Can anyone help please...?


Solution

  • So the issue was that the AngularJS $location service wasn't being updated when the route changed, leaving a disparity between its value and the value being displayed in the browser. There was also a watch in this service which was being triggered in every digest cycle, that was then resetting the browser url from the value in the $location service!

    Turns out this was because I needed to configure the Unified Angular Location Service in my AppModule viz:

    imports: [
      LocationUpgradeModule.config()
    ]
    

    and downgrade the $locationShim service for injection into AngularJS viz:

    angularJS.module('my-app')
      .factory('$location', downgradeInjectable($locationShim));