How do I navigate to a parent route from a child route?

AngularAngular RoutingAngular Router

Angular Problem Overview


My problem is quite classic. I have a private part of an application which is behind a login form. When the login is successful, it goes to a child route for the admin application.

My problem is that I can't use the global navigation menu because the router tries to route in my AdminComponent instead of my AppCompoment. So my navigation is broken.

Another problem is that if someone want to access the URL directly, I want to redirect to the parent "login" route. But I can't make it work. It seems to me like theses two issues are similar.

Any idea how it can be done?

Angular Solutions


Solution 1 - Angular

Do you want a link/HTML or do you want to route imperatively/in code?

Link: The RouterLink directive always treats the provided link as a delta to the current URL:

[routerLink]="['/absolute']"
[routerLink]="['../../parent']"
[routerLink]="['../sibling']"
[routerLink]="['./child']"     // or
[routerLink]="['child']" 

// with route param     ../../parent;abc=xyz
[routerLink]="['../../parent', {abc: 'xyz'}]"
// with query param and fragment   ../../parent?p1=value1&p2=v2#frag
[routerLink]="['../../parent']" [queryParams]="{p1: 'value', p2: 'v2'}" fragment="frag"

With RouterLink, remember to import and use the directives array:

import { ROUTER_DIRECTIVES } from '@angular/router';
@Component({
    directives: [ROUTER_DIRECTIVES],

Imperative: The navigate() method requires a starting point (i.e., the relativeTo parameter). If none is provided, the navigation is absolute:

import { Router, ActivatedRoute } from '@angular/router';
...
constructor(private router: Router, private route: ActivatedRoute) {}
...
this.router.navigate(["/absolute/path"]);
this.router.navigate(["../../parent"], {relativeTo: this.route});
this.router.navigate(["../sibling"],   {relativeTo: this.route});
this.router.navigate(["./child"],      {relativeTo: this.route}); // or
this.router.navigate(["child"],        {relativeTo: this.route});

// with route param     ../../parent;abc=xyz
this.router.navigate(["../../parent", {abc: 'xyz'}], {relativeTo: this.route});
// with query param and fragment   ../../parent?p1=value1&p2=v2#frag
this.router.navigate(["../../parent"], {relativeTo: this.route, 
    queryParams: {p1: 'value', p2: 'v2'}, fragment: 'frag'});

// navigate without updating the URL 
this.router.navigate(["../../parent"], {relativeTo: this.route, skipLocationChange: true});

Solution 2 - Angular

This seems to work for me as of Spring 2017:

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

Where your component ctor accepts ActivatedRoute and Router, imported as follows:

import { ActivatedRoute, Router } from '@angular/router';

Solution 3 - Angular

You can navigate to your parent root like this

this.router.navigate(['.'], { relativeTo: this.activeRoute.parent });

You will need to inject the current active Route in the constructor

constructor(
    private router: Router,
    private activeRoute: ActivatedRoute) {

  }

Solution 4 - Angular

constructor(private router: Router) {}

navigateOnParent() {
  this.router.navigate(['../some-path-on-parent']);
}

The router supports

  • absolute paths /xxx - started on the router of the root component
  • relative paths xxx - started on the router of the current component
  • relative paths ../xxx - started on the parent router of the current component

Solution 5 - Angular

without much ado:

this.router.navigate(['..'], {relativeTo: this.activeRoute, skipLocationChange: true});

parameter '..' makes navigation one level up, i.e. parent :)

Solution 6 - Angular

Another way could be like this

this._router.navigateByUrl(this._router.url.substr(0, this._router.url.lastIndexOf('/'))); // go to parent URL

and here is the constructor

constructor(
    private _activatedRoute: ActivatedRoute,
    private _router: Router
  ) { }

Solution 7 - Angular

To navigate to the parent component regardless of the number of parameters in the current route or the parent route: Angular 6 update 1/21/19

   let routerLink = this._aRoute.parent.snapshot.pathFromRoot
		.map((s) => s.url)
		.reduce((a, e) => {
            //Do NOT add last path!
			if (a.length + e.length !== this._aRoute.parent.snapshot.pathFromRoot.length) {
				return a.concat(e);
			}
			return a;
		})
		.map((s) => s.path);
	this._router.navigate(routerLink);

This has the added bonus of being an absolute route you can use with the singleton Router.

(Angular 4+ for sure, probably Angular 2 too.)

Solution 8 - Angular

My routes have a pattern like this:

  • user/edit/1 -> Edit
  • user/create/0 -> Create
  • user/ -> List

When i am on Edit page, for example, and i need go back to list page, i will return 2 levels up on the route.

Thinking about that, i created my method with a "level" parameter.

goBack(level: number = 1) {
    let commands = '../';
    this.router.navigate([commands.repeat(level)], { relativeTo: this.route });
}

So, to go from edit to list i call the method like that:

this.goBack(2);

Solution 9 - Angular

None of this worked for me ... Here is my code with the back function :

import { Router } from '@angular/router';
...
constructor(private router: Router) {}
...
back() {
   this.router.navigate([this.router.url.substring(0, this.router.url.lastIndexOf('/'))]);
}

this.router.url.substring(0, this.router.url.lastIndexOf('/') --> get the last part of the current url after the "/" --> get the current route.

Solution 10 - Angular

If you are using the uiSref directive then you can do this

uiSref="^"

Solution 11 - Angular

My solution is:

const urlSplit = this._router.url.split('/');
this._router.navigate([urlSplit.splice(0, urlSplit.length - 1).join('/')], { relativeTo: this._route.parent });

And the Router injection:

private readonly _router: Router

Solution 12 - Angular

This might help: https://angular.io/api/router/ExtraOptions#relativeLinkResolution

> ExtraOptions interface
> A set of configuration options for a router module, provided in the forRoot() method. > > interface ExtraOptions { > // Others omitted > relativeLinkResolution?: 'legacy' | 'corrected' > } > > > > relativeLinkResolution?: 'legacy' | 'corrected' > > Enables a bug fix that corrects relative link resolution in components with empty paths. >
<<snip>>
> The default in v11 is corrected.

I've been struggling with routing the last couple of days, turns out there used to be a bug in relative routing. This fixes it.

Solution 13 - Angular

add Location to your constructor from @angular/common

constructor(private _location: Location) {}

add the back function:

back() {
  this._location.back();
}

and then in your view:

<button class="btn" (click)="back()">Back</button>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionCarl BoisvertView Question on Stackoverflow
Solution 1 - AngularMark RajcokView Answer on Stackoverflow
Solution 2 - Angularne1410sView Answer on Stackoverflow
Solution 3 - AngularChris LamotheView Answer on Stackoverflow
Solution 4 - AngularGünter ZöchbauerView Answer on Stackoverflow
Solution 5 - AngularIgor ZininView Answer on Stackoverflow
Solution 6 - AngularJohansrkView Answer on Stackoverflow
Solution 7 - AngularkayjteaView Answer on Stackoverflow
Solution 8 - AngularCarlinhosView Answer on Stackoverflow
Solution 9 - AngularDimitri Dedusse OdyssoundView Answer on Stackoverflow
Solution 10 - AngularZurielView Answer on Stackoverflow
Solution 11 - AngularanlijudavidView Answer on Stackoverflow
Solution 12 - AngularBarry van DrielView Answer on Stackoverflow
Solution 13 - Angularuser3021615View Answer on Stackoverflow