Reputation: 2255
Since the 2.0.0-rc.1
router.navigate
or router.navigateByUrl
doesn't seem to be working anymore correctly when used inside ngOnInit
.
I don't get an error or anything, but it looks like the navigate
happens too early, because right after it the HomeComponent
is loaded and "replaces" the content of the LetterComponent
. However the URL is correct (/letter
).
If I put the navigate in a setTimeout
with 1000ms it works again.
Do I need to use a different lifecycle event or am I doing something wrong? Or is it a bug?
Note that: normally the value which specifies where to navigate to, comes from a cookie (is dynamic).
Here's my simplified app component:
@Component({
selector: 'my-app',
templateUrl: './app/app.component.html',
directives: [ROUTER_DIRECTIVES]
})
@Routes([
{ path: '/', component: HomeComponent },
{ path: '/letter',component: LetterComponent },
{ path: '/cv', component: CVComponent },
{ path: '/attachment', component: AttachmentComponent }
])
export class AppComponent implements OnInit {
constructor(private _router: Router) {
}
ngOnInit() {
// todo: currently not working correctly (issue?)
//also doesn't work: this._router.navigateByUrl("/letter");
this._router.navigate(["/letter"]);
}
}
Here's a demo of what happens.
When I access the app without a path it should directly navigate to the /letter
"page" - as you can see the URL changes, but the content is the wrong one (the content is the one of the home component).
Update:
Here are my imports, if they are of any relevance:
import {Component} from '@angular/core';
import {Router, Routes, ROUTER_DIRECTIVES} from '@angular/router';
import {OnInit} from '@angular/core';
Here's my bootstraping:
import { bootstrap } from '@angular/platform-browser-dynamic';
import {AppComponent} from './app.component';
import {ROUTER_PROVIDERS} from '@angular/router';
import 'rxjs/Rx';
bootstrap(AppComponent, [
ROUTER_PROVIDERS
]);
Regarding @eburgers post:
Here's what I did:
import {Component} from '@angular/core';
import {Routes, ROUTER_DIRECTIVES, Router, ROUTER_PROVIDERS, OnActivate} from '@angular/router';
import {OnInit} from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app/app.component.html',
directives: [ROUTER_DIRECTIVES]
})
@Routes([
{ path: '/', component: HomeComponent },
{ path: '/letter',component: LetterComponent },
{ path: '/cv', component: CVComponent },
{ path: '/attachment', component: AttachmentComponent }
])
export class AppComponent implements OnActivate {
constructor(private _router: Router) {
}
routerOnActivate() {
// todo: currently not working correctly (issue?)
//also doesn't work: this._router.navigateByUrl("/letter");
this._router.navigate(["/letter"]);
}
}
Upvotes: 8
Views: 32910
Reputation: 862
in other cases , probably you have a href="#" in the tag, wich is overriding after router.navigate
Upvotes: 0
Reputation: 1091
You have probably already resolved this by now, but I wonder if the order of your routes is the real problem. If I remember correctly, the router tries to match the path to the one given. So, in your listing, '/letter' matches the route '/' first, so it returns 'HomeComponent'.
I think if you had reordered your routes so that the route '/' was last, then it would have matched '/letter' correctly.
Upvotes: 1
Reputation: 361
I don't know if that's a bug or you are doing anything wrong. But instead of using the timeout method, I would suggest following approach:
ngOnInit() {
this.redirectToPath();
}
redirectToPath() {
this._router.navigate(["/letter"]);
}
Upvotes: 0
Reputation: 2255
I'm pretty sure it's a bug. I opened a new issue on github: https://github.com/angular/angular/issues/8733
When I get an answer / it's fixed I'll update this answer here with the solution (if there is any).
In the meantime there is a workaround, see @funkycoder post. Even though the workaround is for most users probably also not satifying.
Upvotes: 2
Reputation: 583
UPDATE
So, I downloaded your code to see what the issue is.
navigate()
instead of
navigateByUrl()
. So you might want to change that.To resolve the issue, you simply need to put the current root route into a separate subroute, eg. /home
.
{ path: '/home', component: HomeComponent }
I could not find any documentation for this behavior, but for a reason similar to this, even the Angular tutorial at angular.io does not have a root route. It only has /dashboard
, /heroes
and /detail/:id
.
PREVIOUS ANSWER
Looks like you are missing the ROUTER_PROVIDER in the @Component declaration. Try adding that as:
@Component({
selector: 'my-app',
templateUrl: './app/app.component.html',
directives: [ROUTER_DIRECTIVES],
providers: [ROUTER_PROVIDERS]
})
Also, import the appropriate references:
import {Routes, Router, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from '@angular/router';
Upvotes: 6
Reputation: 14979
Try moving it into routerOnActivate
instead of ngOnInit
.
You can do it by importing OnActivate
and implementing it in your class.
Also make sure you are bootstraping your app with ROUTER_PROVIDERS
.
Upvotes: 2
Reputation: 79
Probably you should do that trick
setTimeout(() => this._router.navigate(["/letter"]), 0);
Upvotes: 6