I am using UI Router 0.2.15 with Angular 1.4.3. Some of my pages can open a Twitter Bootstrap modal. By default, there is no way to link directly to an open modal, so I wrote a custom directive that will listen to a query parameter in the URL to open and close the modal. If the query parameter is present, it opens the modal, if not, it closes it. This comes in handy when users want to link to different modals on the same page, or simply want to deeplink to a modal. So buttons that used to trigger some JavaScript to open a modal now just link to a slightly different route instead that will open the modal through the directive.
This is handled by the following code from my directive:
scope.$watch(function () {
return $state.params[param];
}, function (param) {
$timeout(function () {
if (param) {
element.modal('show');
} else {
element.modal('hide');
}
}, 0, false);
}, true);
// When the modal is closed, remove the param from the URL
element.on('hidden.bs.modal', function () {
$state.params[param] = undefined;
scope.$apply(function () {
$state.go($state.current, $state.params);
});
});
This works fine, but here's my problem. Imagine the following flow:
- You open page a
- You open page b
- You click on a link to a modal at
?_id=1
- The query param
_id=1
is appended, the modal is opened - You close the modal, the query param is removed
- You go back in history
- It reopens the modal, since the last entry in history contains the query parameter
The modal is reopened, even though the user expects to end up on page a. After all, that was the last page the user visited.
In other words, how do I make the modal not have any effect on the browser's history, even though it's linkable?
My first idea was to replace the last entry in history whenever the query param changes. However, once the modal is opened, it's too late to do that, since I would need to access the second to last history entry and replace it with the current one, which, as far as I know, is impossible.
Ideally, there would be something like { location: 'replace' }
on query parameter changes, that can be defined as another option in the routes.
I also checked Can you use hash navigation without affecting history? and AngularJS redirect without pushing a history state, to no avail.