Angular 4: Routing to a route doesn't work
Asked Answered
L

2

10

There is some fundamental concept of routing in Angular 4 that I don't understand.

index.html:

<base href="/">

File structure:

- app
|- app.routings.ts
|- collections
|-- collection.component.ts
|-- collection.component.html
|-- collectioninfo.component.ts
|-- collectioninfo.component.html
|- shared
|-- header.component.html
|-- header.component.ts

I have a link in my header.component.html:

<a class="nav-link" [routerLink]="['/collections']">
    Collections
</a>

If I click it I land on localhost:4200/collections. When a button is clicked, the url is programmatically changed (in collection.component.ts):

this.router.navigate(['/collections/', collection.name]);

I end up on localhost:4200/collections/name - all fine. Now I programatically want to get back to /collections (in collectioninfo.component.ts):

this.router.navigate(['/collections']);

But that doesn't work. The url doesn't change and I get an error that says a parameter couldn't be loaded - so apparently /collections/name is being loaded again. Thought it might is a path issue, but things like this also don't work:

this.router.navigate(['../collections']);

Additional info: When I manually reload the page while being on /collections I'm being forwarded to the home page again, but I think that is another issue and not related to this behaviour.

app.routing.ts:

const APP_ROUTES: Routes = [
  ...
  { path: 'collections', component: CollectionComponent },
  { path: 'collections/:id', component: CollectionInfo },
];
Loutish answered 13/9, 2017 at 15:3 Comment(15)
have you tried navigateByUrl instead of navigate, I don't know if it will fix your issue, but I use that for my programmatic page changesIncisive
Thanks for the hint, unfortunately that doesn't work either (some behaviour).Loutish
how is your empty path defined and what is isAuthenticated in your header?Karyoplasm
Flip the order of your routes, making the most specific route first. The reason you're getting the error regarding the missing parameter is because /collections is falling through to the CollectionsInfo route. Alternatively, use an exact match for the route.Postaxial
maybe it is syntaxual? Try without the brackets this.router.navigateByUrl('/collections');Incisive
@Brandon: Flipping the order doesn't work - I put { path: 'collections/:id', component: CollectionInfo } to the very top, but without success. How would I use an exact match of the route? You mean the path in the link?Loutish
@JayDeeEss: Sorry about "isAuthenticated" - forgot to put that out. This part of the menu is hidden for non-authenticated users. Put it out now. The empty path (if that's would you mean, sorry, I'm not so familiar with Angular 2 yet) is { path: '', component: HomeComponent, pathMatch: 'full' }.Loutish
@Surreal: It just works without the brackets anyway. But thanks for the hint.Loutish
@Loutish try: pathMatch: 'full'Postaxial
@Brandon: No, unfortunately that doesn't work.Loutish
There are some posts suggesting that the current page might gets reloaded because of clicking a button that lacks "type='button'" (#39002209), but I get the same behaviour after adding the type.Loutish
Can you provide a reproducable plunkr? I have a similar setup but no issues and can't really spot an error here. (using navigate the first part is always relative to the base if you use it like navigate(['/collections']), so nothing wrong with that. Guess your components don't try to redirect onInit or something like that?Influential
@lexith: Thanks for the suggestion, will do. Before I do so can you please just elaborate what you mean with "components don't try to redirect onInit"? Why should my components redirect somewhere?Loutish
I just wanted to ask if there could be some other components / services that mess with your routes. well i guess you dont have a router.navigate in your ngOnInit but maybe you have a Guard somewhere that intervenes with your routing? I dont know, that's why i wanted to see more of your code :)Influential
@lexit Thanks a lot for helping me out. I found the issue, posted it as answer below.Loutish
L
6

Turns out my firebase code is messed up - it tries to reload the page before going to another route. That caused an error, because some parameters that handed over from the previous route were missing.

export const routing = RouterModule.forRoot(APP_ROUTES, { enableTracing: true })

in app.routing.ts was very useful for debugging.

Loutish answered 18/9, 2017 at 0:15 Comment(0)
J
5

In your relative path this.router.navigate(['../collections']); you are trying to navigate to localhost:4200/collections/collections. Try this.router.navigate(['../']);

If this doesn't work, also supply the ActivatedRoute as a relativeTo parameter:

constructor(route: ActivatedRoute, router: Router) {}

navigate() {
  this.router.navigate(['../'], { relativeTo: this.route });
}

relativeTo works by creating a path relative to whatever entry you provide, and it does not necessarily need to be the current route.

Jarl answered 13/9, 2017 at 15:39 Comment(5)
this.router.navigate(['../']) doesn't throw an error, but it leads me to my homepage. this.router.navigate(['../collections']) doesn't work though, it throws the same error as stated above. I then tried ActivatedRoute: Imported it (import { ActivatedRoute } from '@angular/router';) and put it in the constructor, but "relativeTo: route" throws a syntax error: Cannot find name "route" any. Although it's properly written in the constructor: route: ActivatedRoute. Do you have a hunch why it's behaving like that?Loutish
Try changing route to this.route. I make this mistake more often than I'd like to admit.Jarl
This could be pretty embarrassing, but I have no clue what I'm doing wrong syntax wise. Must be a small thing, but I don't see it. As it's not related to the original issue I thought it's better to post this on pastebin: pastebin.com/CY3M2Gvk. Can you spot any obvious error there?Loutish
I don't see anything wrong with what you have there, and using this.router.navigate(['/collections']); should have worked fine as well. Maybe there is something else.. But I don't see anything wrong with what you have. I'm sorry I couldn't help any more :(Jarl
I missed "public" in the constructor. But still relativeTo doesn't solve the problem. Thanks for your help though.Loutish

© 2022 - 2024 — McMap. All rights reserved.