I'm having a very odd issue with Angular 2 routing to where my ngOnInit in the component that I am routing to is getting called twice, and the route in the browser is getting reset to the original route.
I have a NotificationListComponent and a NotificationEditComponent in a MaintenanceModule.
In my root AppModule, I setup the RouterModule to redirect any unmapped routes to /maintenance/list.
app.module.ts:
@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    HttpModule,
    RouterModule.forRoot([
      {path: "", redirectTo: "maintenance/list", pathMatch: "full"},
      {path: "**", redirectTo: "maintenance/list", pathMatch: "full"}
    ], {useHash: true}),
    CoreModule.forRoot({notificationUrl: "http://localhost:8080/notification-service/notifications"}),
    MaintenanceModule
  ],
  providers: [NotificationService],
  bootstrap: [AppComponent]
})
export class AppModule { }
And I have the /maintenance/list route defined in my MaintenanceModule, which points at my NotificationListComponent, as well as a /maintenance/edit/:id route which points at my NotificationEditComponent.
maintenance.module.ts:
@NgModule({
  imports: [
    CommonModule,
    RouterModule.forChild([
      {path: "maintenance/list", component: NotificationListComponent, pathMatch: 'full'},
      {path: "maintenance/edit/:id", component: NotificationEditComponent, pathMatch: 'full'}
    ]),
    FormsModule
  ],
  declarations: [
    NotificationListComponent,
    NotificationEditComponent
  ]
})
export class MaintenanceModule {}
When my application loads, it correctly follows the /maintenance/list route, and I can see all of my notifications in a list. For each notification in the list there is an edit icon, which has its click event bound to the edit(id: number) method in my NotificationListComponent
notification-list.component.ts:
@Component({
  templateUrl: 'notification-list.component.html'
})
export class NotificationListComponent implements OnInit {
  notifications: Notification[];
  errorMessage: string;
  constructor(private _notificationService: NotificationService,
              private _router: Router) {}
  ngOnInit(): void {
    this._notificationService.getNotifications()
      .subscribe(
        notifications => this.notifications = notifications,
        error => this.errorMessage = <any>error);
  }
  clearError(): void {
    this.errorMessage = null;
  }
}
notification-list.component.html:
<div class="row">
  <h1>Notification Maintenance</h1>
  <div *ngIf="errorMessage" class="alert-box alert">
    <span>{{errorMessage}}</span>
    <a class="right" (click)="clearError()">×</a>
  </div>
  <p-dataTable [value]="notifications" [sortField]="'code'" [responsive]="true" [sortOrder]="1" [rows]="10" [paginator]="true" [rowsPerPageOptions]="[10,50,100]">
    <p-header>Available Notifications</p-header>
    <p-column [field]="'code'" [header]="'Code'" [sortable]="true" [style]="{'width':'10%'}"></p-column>
    <p-column [field]="'name'" [header]="'Name'" [sortable]="true" [style]="{'width':'40%'}"></p-column>
    <p-column [field]="'roles'" [header]="'Roles'" [style]="{'width':'40%'}"></p-column>
    <p-column [field]="'notificationId'" [header]="'Edit'" [style]="{'width':'10%'}">
      <template let-row="rowData" pTemplate="body">
        <a [routerLink]="'/maintenance/edit/' + row['notificationId']"><span class="fa fa-pencil fa-2x"></span></a>
      </template>
    </p-column>
  </p-dataTable>
</div>
As you can see, the edit(id: number) method should navigate to the /maintenance/edit/:id route. When I click the icon to navigate to that route, the browser flashes the correct route in the address bar (e.g. localhost:4200/#/maintenance/edit/2), but then the route in the address bar immediately changes back to localhost:4200/#/maintenance/list. Even though the route returned to /maintenance/list in the address bar, my NotificationEditComponent is still visible in the actual application. However, I can see that the ngOnInit method is being called twice in my NotificationEditComponent, because the id gets logged to the console twice, and if I put a breakpoint in the ngOnInit function, it hits that breakpoint twice.
notification-edit.component.ts:
@Component({
  templateUrl: "notification-edit.component.html"
})
export class NotificationEditComponent implements OnInit{
  notification: Notification;
  errorMessage: string;
  constructor(private _notificationService: NotificationService,
              private _route: ActivatedRoute,
              private _router: Router) {
  }
  ngOnInit(): void {
    let id = +this._route.snapshot.params['id'];
    console.log(id);
    this._notificationService.getNotification(id)
      .subscribe(
        notification => this.notification = notification,
        error => this.errorMessage = <any>error
      );
  }
}
This appears to also be causing other issues, because when attempting to bind input values to values in my NotificationEditComponent using, for example [(ngModel)]="notification.notificationId", the value is not being displayed on the screen, even though I can see with the Augury chrome extension, as well as logging the object to the console, that the value is populated in the component.
notification-edit.component.html:
<div class="row">
  <h1>Notification Maintenance</h1>
  <div *ngIf="errorMessage" class="alert-box alert">
    <span>{{errorMessage}}</span>
    <a class="right" (click)="clearError()">×</a>
  </div>
  <p-fieldset [legend]="'Edit Notification'">
    <label for="notificationId">ID:
      <input id="notificationId" type="number" disabled [(ngModel)]="notification.notificationId"/>
    </label>
  </p-fieldset>
</div>
Does anyone have any idea why this would be happening?
Update:
I removed my calls to the NotificationService, and replaced them with just some mock data, and then the routing started working! But as soon as I add calls to my service, I get the same issue I described above. I even removed the CoreModule and just added the service directly to my MaintenanceModule, and still got the same issue whenever I use the actual service instead of just mock data.
notification.service.ts:
@Injectable()
export class NotificationService {
  private _notificationUrl : string = environment.servicePath;
  constructor(private _http: Http) {
  }
  getNotifications(): Observable<Notification[]> {
    return this._http.get(this._notificationUrl)
      .map((response: Response) => <Notification[]>response.json())
      .catch(this.handleGetError);
  }
  getNotification(id: number): Observable<Notification> {
    return this._http.get(this._notificationUrl + "/" + id)
      .map((response: Response) => <Notification>response.json())
      .catch(this.handleGetError);
  }
  postNotification(notification: Notification): Observable<number> {
    let id = notification.notificationId;
    let requestUrl = this._notificationUrl + (id ? "/" + id : "");
    return this._http.post(requestUrl, notification)
      .map((response: Response) => <number>response.json())
      .catch(this.handlePostError);
  }
  private handleGetError(error: Response) {
    console.error(error);
    return Observable.throw('Error retrieving existing notification(s)!');
  }
  private handlePostError(error: Response) {
    console.error(error);
    return Observable.throw('Error while attempting to save notification!');
  }
}
And the service seems to run fine - I can see that the endpoint successfully returns data and I can see that the data looks correct when I look at my NotificationEditComponent with the Augury chrome extension. But the data does not show in the template, and the route in the URL returns to /maintenance/list even though the template for the /maintenance/edit/:id route is still displayed.
Update 2:
As suggested by @user3249448, I added the following to my AppComponent for some debugging:
constructor(private _router: Router) {
  this._router.events.pairwise().subscribe((event) => {
    console.log(event);
  });
}
Here is the output of that when I click on one of the "edit" links:

 
     
    
