I am developing an angular2 app and I use router. I am in a page /myapp/signup. after signup I navigate the use to /myapp/login. /myapp/login can also be navigated from my home page which is /myapp. So now, when the user users /myapp/login I go back. This can be done by using location.back(). But I dont want to go back when the user is coming from /myapp/signup. So I should check if the user is coming from /myapp/signup and if so, I want to direct it to somewhere else. How can I know the previous url so that I direct the user to a specific state based on that ?
8 Answers
The pairwise operator allows to get the current together with the previous value
update
import 'rxjs/add/operator/pairwise'; import 'rxjs/add/operator/filter'; import { Router, NavigationEnd } from '@angular/router'; export class AppComponent { constructor(private router: Router) { this.router.events .filter(e => e instanceof NavigationEnd) .pairwise().subscribe((e) => { console.log(e); }); } } See also How to detect a route change in Angular?
original (super old)
Inject Router and subscribe to events and store them for later reference
constructor(private _router: Router) { this._router.subscribe(route => { this.nextRoute ... this.prevRoute ... }); 13 Comments
e when I use the update example above? Currently hacking it like so: const prev = <NavigationEnd>e[0] const cur = <NavigationEnd>e[1] console.log('Previous url' + prev.url) console.log('Previous url' + cur.url)Yes, I would do it this way:
@Injectable() // do not forget to register this class as a provider export class PreviousRouteRecorder implements CanDeactivate<any> { constructor(private router: Router) { } canDeactivate(component: any): Observable<boolean> | boolean { localStorage.setItem('previousRoute', this.router.url); return true; } } export const ROUTES: Routes = [ { path: 'first', component: FirstComponent, canDeactivate: [PreviousRouteRecorder]}, { path: 'second', component: SecondComponent } ]; export class SecondComponent implements OnInit { ngOnInit(){ console.log(localStorage.getItem('previousRoute')); } } Comments
Angular 6 updated code for getting previous url as string.
import { Component, OnInit } from '@angular/core'; import { Router, RoutesRecognized } from '@angular/router'; import { filter, pairwise } from 'rxjs/operators'; export class AppComponent implements OnInit { constructor ( public router: Router ) { } ngOnInit() { this.router.events .pipe(filter((e: any) => e instanceof RoutesRecognized), pairwise() ).subscribe((e: any) => { console.log(e[0].urlAfterRedirects); // previous url }); } Comments
You can do this with document.referrer
if(document.referrer !== '/myapp/signup'){ location.back() } 4 Comments
You can maybe leverage the OnActivate phase with the routerOnActivate method that gives you access to the previous url and the current one.
routerOnActivate(next: ComponentInstruction, prev: ComponentInstruction) { console.log(`Finished navigating from "${prev ? prev.urlPath : 'null'}" to "${next.urlPath}"`); } The implementation with the pairwise will not work if the user doesn't trigger navigation event at least two times and may cause a small bug.
page 1 -> page 2 ---> navigation event triggered, but event Observable has only 1 value and thus pairwise does not emit ---> User cannot go back to page 1
page 2 -> page 3 --> event Observable now has 2 elements and pairwise emits
I wonder if there is a workaround?
4 Comments
import {Location} from '@angular/common'; private currentLocation; constructor(private location: Location){ this.currentLocation = this.location.path(); } ngAfterViewInit() { let instance = this; this.router.parent.subscribe(() => { if (instance.currentLocation != instance.location.path()) { console.log("previous -> "+instance.currentLocation+" != next -> "+instance.location.path()); }else{ console.log("previous -> "+instance.currentLocation+" == next -> "+instance.location.path()); } }); }