Issue 1:
I'm submitting a ... (check one with "x")

[x] bug report => search github for a similar issue or PR before submitting
[ ] feature request
[ ] support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question

Current behavior

When using HashLocationStrategy and change url manually to the one, which is protected by CanActivate guard (this returns false and fire redirect to the other page), navigation events are called twice.

Expected behavior

All navigation event are called once only.

Minimal reproduction of the problem with instructions

Use the demo in http://plnkr.co/edit/4xlYD9wmetG5G0Dvjp0E?p=preview

Open window mode http://run.plnkr.co/plunks/4xlYD9wmetG5G0Dvjp0E/#/component-one

Click Guarded Component Two link - only one NavigationStart and NavigationCancel events logged in console.

Manually change url from /#/component-one to /#/component-two and hit enter - two pair of NavigationStart and NavigationCancel events logged in console.

What is the motivation / use case for changing the behavior?

As the duplication of navigation event causes guards logic to be executed twice (and this may contain API calls) - it is a performance issue. Potentially, if guard resolving depends on some conditions which are true after first failed attempt - the second one will be successful, however it is not desired behavior.

Please tell us about your environment:

Angular version: 4.1.0

Browser: Chrome 57

Language: TypeScript

Issue 2:
I'm submitting a ... (check one with "x")

[X ] bug report => search github for a similar issue or PR before submitting
[ ] feature request
[ ] support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question

Current behavior

Currently, I have a deactivation guard on a route which will return false or true depending on a condition. To get to this guarded route, the user must pass though 3 navigation step. Now, once on the guarded route, when using location.back(), the guard is called. If it returns true, the previous route is loaded. If the guard returns false, the navigation is cancelled. But if we redo a Location.back() after a failed navigation, the previous route that will be loaded will be 2 steps in the history instead of 1 (user perception).

Workflow

Main -- navigate to --> Route 1
Route 1 -- navigate to --> Route 2
Route 2 -- navigate to --> Route 3
Route 3 -- location.back() --> guard returns true --> Route 2
Route 2 -- navigate to --> Route 3
Route 3 -- location.back() --> guard returns false --> Route 3
Route 3 -- location.back() --> guard returns true --> Route 1 (should be Route 2)

Expected behavior

An expected behavior for a user would be that navigating back brings back to the previous routed page.

Workflow

Main -- navigate to --> Route 1
Route 1 -- navigate to --> Route 2
Route 2 -- navigate to --> Route 3
Route 3 -- location.back() --> guard returns true --> Route 2
Route 2 -- navigate to --> Route 3
Route 3 -- location.back() --> guard returns false --> Route 3
Route 3 -- location.back() --> guard returns true --> Route 2 (expected)

Minimal reproduction of the problem with instructions

Plnkr

Click button Nav to route1

Click button Nav to route2

Click button Nav to route3

Click button Block Nav Back

Click button Nav back

BOGUE: The location.back() routed on Route1 instead of Route2

Personnal investigation

After some investigation, I saw that in routerState$.then (router.ts line 752) this logic used when navigationIsSuccessful == false is pretty simply but it is the actual cause of this bug. Basically, when a deactivation guard is hit, the location of the browser is already changed to the previous route. Which means that when the guard returns false, the routerState$ runs his logic and calls resetUrlToCurrentUrlTree(). At this point we can see that we replace the state of the current location. But by doing this, we loose that route in the history which means that in my plunker, if we click the block nav back 3 times and then click the nav back we will actually kill the application.

What is the motivation / use case for changing the behavior?

This is for me a pretty big bug since a guard that returns false breaks alters the current routing history. In the case of our application this breaks the workflow and brings wrong business scopes to a user.

Please tell us about your environment:

Windows 10, NPM, Nodejs, Visual Studio 2015 (using nodejs for typescript compilation)

Angular version: 2.3.3

Browser: [ all ]

Language: [TypeScript 2.0.10 | ES5]