On an application my team and I are working on, we're observing some inconsistent behavior. When a user performs a browser refresh, the refresh button fully refreshes the page including UI state...but only does that up to a certain route.
Our App starts on the /Home
route, which sets up the overall application, as well as the component hierarchy. The user proceeds to A.A
, A.B
, A.C
, which all function fine. B.A
works fine as well.
Then, trouble. If you perform a browser refresh from B.B
or B.C
, you get returned to B.A
. We expect that the end-user would be returned to B.B
or B.C
if they refresh from those pages.
Routes.ts
$stateProvider
.state('Home',
{
url: '/Home',
templateUrl: 'App/Home/home.html',
controller: 'homeCtrl',
controllerAs: '$ctrl'
})
.state('A',
{
url: '/A',
templateUrl: 'app/A/A.html',
controller: 'aCtrl',
controllerAs: '$ctrl'
})
.state('A.A',
{
url: '/A.A',
component: 'aPartA'
})
.state('A.B',
{
url: '/A.B',
component: 'aPartB'
})
.state('A.C',
{
url: '/A.C',
component: 'aPartC'
})
.state('B',
{
url: '/B',
component: 'b'
})
.state('B.A',
{
url: '/B.A',
component: 'bPartA'
})
// Beyond this part, oddness starts...
.state('B.B',
{
url: '/B.B',
component: 'bPartB'
})
.state('B.C',
{
url: '/B.C',
component: 'bPartC'
});
$urlRouterProvider.otherwise('/Home');
$locationProvider.html5Mode({ enabled: true});
The way we actually perform our routing, is using a component!
Relevant HTML:
<order-navigation validate-view="$ctrl.validate(someForm)"
previous-route="A.C"
previous-button-text="previous"
next-route="B.A"
next-button-text="continue">
</order-navigation>
Order Navigation Component Controller:
export class OrderNavigationCtrl implements angular.IController {
//#region Variables / Properties
public nextRoute: string;
public previousRoute: string;
public nextButtonText: string;
public previousButtonText: string;
public validateView : () => boolean;
//#endregion Variables / Properties
//#region Constructor
public static $inject: string[] = ['$state', '$window'];
constructor(
private $state: angular.ui.IStateService,
private $window: angular.IWindowService) {
}
public $onInit(): void {
}
//#endregion Constructor
//#region Methods
public navigatePrevious(route: string): void {
if (route.search('www') > 0)
this.$window.open(route, '_self');
else
this.$state.go(route);
}
public navigateNext(route: string): void {
if (this.validateView())
this.$state.go(route);
}
//#endregion Methods
}
I've checked each page's HTML, and found no typos that would cause B.B or B.C to redirect to B.A. As we're using a common component, I would expect that if the flaw were in the component controller, it would affect all pages equally, and cause any page refresh to fall back to a common point, which is not the case.
Questiosn:
A: What's causing B.B and B.C to redirect to B.A, instead of themselves?
B: In what way can I change this to ensure that B.B and B.C redirect to themselves?
Possible Workaround:
One thing my research has suggested that I can do is to use localStorage
and .run()
to cache the UI router state. I would like to avoid this, because ideally this routing should 'just work'; we're not doing anything special. If there is something we're doing incorrectly in this, I also need to know what it is, so that my team and I don't do that incorrect thing.