Search code examples
angularangular-router

Angular router navigation problems


I'm having trouble understanding how the Angular Router.

Here's my issue: I'm currently in this url/route -

https://localhost:4200/#/db/accounts/resetpassword?userId=7&resetToken=xyz

When I navigate using the Router + ActivatedRoute

this._router.navigate(['login'], { relativeTo: this._actRoute })
this._router.navigate(['./login'], { relativeTo: this._actRoute })
this._router.navigate(['../login'], { relativeTo: this._actRoute })
this._router.navigate(['../../login'], { relativeTo: this._actRoute })

...I get sent to

https://localhost:4200/#/db/accounts/resetpassword/login

When I navigate to

this._router.navigate(['../../../login'], { relativeTo: this._actRoute })

...I get sent to

https://localhost:4200/#/db/accounts/login

...which is where I want to be sent to.

My question is, how come the last one replaces the end segment of the url and the previous 4 don't. I feel like I'm missing some fundamental piece of how routing works.


Solution

  • For anyone interested this is how I'm solving it now. I don't really trust

    this._router.navigate(['../../../login'], { relativeTo: this._actRoute })
    

    because from different modules this works

    this._router.navigate(['../../login'], { relativeTo: this._actRoute })
    

    If anyone knows a better way please comment. Also this might need some extra checks for fragments etc.

            import { Router } from '@angular/router';
    
        //-------------------------------------------------//
    
        /**
         * Replaces everything after the last '/' in currentUrl with replacementSegment.    
         * Will also remove any paramaters. 
         * @param currentUrl url to change
         * @param replacementSegment what to put at the end of the altered url
         * @returns the altered url
         */
        export function ReplaceLastUrlSegment(currentUrl: string, replacementSegment: string): string {
    
            if (!currentUrl)
                return '/' + replacementSegment
    
            //remove any paramaters
            const segments = currentUrl.split('?')
            if (!segments?.length)
                return '/' + replacementSegment
    
            return segments[0].split('/').slice(0, -1).join('/') + '/' + replacementSegment
    
    
        }//ReplaceLastUrlSegment
    
        //-------------------------------------------------//
    
        /**
         * Replaces everything after the last '/' in router.url with replacementSegment.    
         * Will also remove any paramaters. 
         * @param router current router
         * @param replacementSegment what to put at the end of the altered url
         * @returns the router's altered url
         */
        export function ReplaceLastUrlSegmentFromRouter(router: Router, replacementSegment: string): string {
    
    
            //Don't null check it.
            //It should crash if router is null
            return ReplaceLastUrlSegment(router.url, replacementSegment)
    
        }//ReplaceLastUrlSegmentFromRouter
    
        //-------------------------------------------------//
    
        /**
         * Replaces everything after the last '/' in router.url with replacementSegment.  Then navigates to new url.
         * Will also remove any paramaters. 
         * @param router current router
         * @param replacementSegment what to put at the end of the altered url
         */
        export function ReplaceLastUrlSegmentAndNavigate(router: Router, replacementSegment: string) {
    
            //Don't null check it.
            //It should crash if router is null
    
            const newUrl = ReplaceLastUrlSegment(router?.url, replacementSegment)
            router.navigateByUrl(newUrl)
    
    
        }//ReplaceLastUrlSegmentFromRouter
    
        //-------------------------------------------------//