I am having an issue with the new Angular 2 router. I have a button click event that calls a function to route to a dashboard page from a login component. both are child components of the main app component. when I click the button and the function fires I use the navigateByUrl() function to navigate to the dashboard page from the login. but when that function is called, the browser url shows localhost:52370/dashboard? and a black page in the browser. Im not sure where this problem originates from. here is my app.routes.ts file
const appRoutes: Routes = [
{ path: "", component: HomeComponent },
{ path: "home", redirectTo: "" },
{ path: "login", component: LoginComponent },
{ path: "dashboard", component: DashboardComponent },
];
export const AppRoutingProviders: any[] = [];
export const AppRouting: ModuleWithProviders = RouterModule.forRoot(appRoutes);
login.component.ts file
constructor(private router: Router, private route: ActivatedRoute) { }
public login() {
this.loginStatus = true;
this.onLogin.emit(this.loginStatus);
this.router.navigateByUrl("dashboard")
.then(function () {
console.log("success");
}).catch(function (err) {
console.log(err);
});
}
So I've had similar issues getting blank pages on navigateByUrl() calls. One of the things I discovered is they seem to be timing related issues as I'm bouncing around between redirects. My current setup consists of the following routes:
After login and subsequent redirect to / or on hitting / directly, the RedirectComponent checks for authenticated status and determines if the user is an admin or not. Then navigateByUrl() is called to send the user to the correct route. Note that the first navigate to / has not fully completed yet though, which can be seen from the global router event listener I have wired up:
_router.events.subscribe((event:Event) => {
if (event instanceof NavigationEnd) {
// When the route is '/', location.path actually returns ''.
let newRoute = this._location.path() || '/';
// If the route has changed
if (this.currentRoute !== newRoute) {
console.log('App(): new route', this.currentRoute, newRoute);
this.currentRoute = newRoute;
}
}
});
When doing a navigateByUrl('/'), this loads up my RedirectComponent as expected, which then calls navigateByUrl('/dashboard'). This results in the page loading completely blank and the /dashboard navigate route event never firing. I think there may be some logic that prevents a navigate until the previous navigation completes? My router event listener prints the following right before things stop routing and the blank screen appears:
App(): new route "/login" "/" (2)
As you can see by the (2), it appears that in Safari all the routing happens twice somehow, whereas in Chrome it only happens once. It may even be that some of the logic preventing the /dashboard route from firing may have been "fixes" to handle some underlying issues with browsers like Safari where events / components are firing twice and you don't want multiple navigations actually occurring...? Pure speculation though.
There may be a better way to address the underlying issue, but I have found a simple, albeit inelegant, solution which all of us Angular veterans have in our tool chest for cases where timing issues arise. Our good old frenemy setTimeout(..., 0):
setTimeout(() => {
this.router.navigateByUrl('/dashboard');
}, 0);
The /dashboard route then activates properly and the navigation occurs as expected, AFTER the / navigation completes. There may be a better mechanism or an alternate monkey patch using ChangeDetectorRef or the like, but this gets the job done well enough for me for now. Ship it.
Might be worth a shot just to rule things in or out. Hope this helps. If you find a different solution, that would a helpful follow up for others having similar issues.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With