Retrieve the previous route in Angular 7

I have developed a unique service that allows me to store route changes efficiently.

import { Injectable } from '@angular/core';
import { Router, NavigationEnd } from '@angular/router';

@Injectable()
export class RouteState {

  private previousRoute: string;
  private currentRoute: string;

  constructor(private router: Router) {
    this.currentRoute = this.router.url;    
    router.events.subscribe(event => {
      if (event instanceof NavigationEnd) {        
        this.previousRoute = this.currentRoute;
        this.currentRoute = event.url;
      };
    });
  }

  public getPreviousRoute() {
    return this.previousRoute;
  }    
}

However, I am facing an issue where the currentRoute and previousRoute variables become undefined every time there is a route change. Can anyone suggest a solution?

Answer №1

Utilize the built-in Location service from Angular by importing it from '@angular/common'. Here's how you can do it:

import { Component, OnInit, Input } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Location } from '@angular/common';

import { Hero }         from '../hero';
import { HeroService }  from '../hero.service';

@Component({
  selector: 'app-hero-detail',
  templateUrl: './hero-detail.component.html',
  styleUrls: [ './hero-detail.component.css' ]
})
export class HeroDetailComponent implements OnInit {
  @Input() hero: Hero;

  constructor(
    private location: Location
  ) {}

  goBack() {
    this.location.back();
  }   
}

You can then use location.back() to navigate back to the previous page. Check out this working example:

https://stackblitz.com/angular/qvvrbgrmmda

Answer №2

If you're looking to retrieve your previous route in an Angular application using @angular/router, here's a helpful method:

To learn more, check out the details on the original article

import { Injectable } from '@angular/core';
import { Router, RouterEvent, NavigationEnd } from '@angular/router';
import { filter } from 'rxjs/operators';

@Injectable({
    providedIn: "root"
})
export class PreviousRouteService {

    private previousUrl: string;
    private currentUrl: string;

    constructor(private router: Router) {

        this.currentUrl = this.router.url;
        this.previousUrl = null;

        this.router.events
                    .pipe(filter((event: RouterEvent) => event instanceof NavigationEnd))
                    .subscribe((event: NavigationEnd) => {
                        this.previousUrl = this.currentUrl;
                        this.currentUrl = event.urlAfterRedirects;
                        console.log("prev: ", this.previousUrl)
                        console.log("curr: ", this.currentUrl)
                    });

    }

    public getPreviousUrl() {
        return this.previousUrl;
    }

};

Answer №3

For obtaining the preceding route exclusively, you have the option of creating an observable in this manner:

 public previousRoute$: Observable<string> = this.router.events.pipe(
   filter((e) => e instanceof RoutesRecognized),
   pairwise(),
   map((e: [RoutesRecognized, RoutesRecognized]) => e[0].url)
 );

You can now subscribe to this observable and execute any code (Ensure to unsubscribe from this observable during the OnDestroy event.)

this.previousRoute$.subscribe(url => {
  //execute your functionality
});

REMARK: This observable will commence emitting events once the user navigates to the 2nd page.

Answer №4

If you're not keen on utilizing Angular's Location Service, there is an alternative service you can explore.

// custom service for retrieving previous route
@Injectable()
export class RouteBackService {
    public getPreviousUrl(routeArray): string {
        let prevRoute = '';
        for (let i = 0; i < routeArray.length - 1; i++) {
            if (routeArray[i].url._value[0].length > 0) {
                prevRoute += routeArray[i].url._value[0].path + '/';
            } 
        }
        return prevRoute.slice(0, -1);
    }
}

// implementation in the component to navigate back    
export class YourComponent {
    constructor (private _aRoute: ActivatedRoute,
                   private _routeBack: RouteBackService
                   private _router: Router) {}
    goBack() {
        const prevRoute=this._routeBack.getPreviousUrl(this._aRoute.pathFromRoot);
        this._router.navigate([prevRoute]);
    }
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

There is no index signature that accepts a parameter of type 'string' in the type '{ [key: string]: AbstractControl; }'

I'm currently tackling a challenge in my Angular project where I am creating a custom validator for a reactive form. However, I've encountered an error within the custom validators function that I am constructing. Below you will find the relevan ...

Guide to employing Axios types in project declaration files

When working on my project's type declaration file, I encountered a dilemma with using Axios types as part of my own types. The issue lies in the fact that all declarations for Axios are exported from their official repository. I specifically need to ...

Setting up the primary and thumbnail Swiper in Angular can be a bit tricky, especially when the initialization is set to false. This tutorial focuses on initializing Swiper 11.0

I have incorporated Swiper into several of my components, and I am facing an issue when Angular routing changes, especially with routeParams like /route/:id – it doesn't work correctly. To tackle this problem, I decided to implement ngZone. Although ...

Utilizing Angular's Template-driven Forms for User Authentication and Registration

I am currently looking into using a template-driven Angular form to create a signup and login interface for users. Despite learning about the disadvantages of template-driven forms in cases where complex validation is needed, this particular project does ...

Leverage the Node Short ID library in conjunction with Angular 6 using TypeScript

I attempted to utilize the node module within an Angular 6 typescript environment. Step one: npm i shortid Within my TypeScript class: import { shortid } from 'shortid'; let Uid = shortid.generate(); However, I encountered an error stating ...

Using leaflet-markercluster in Angular 2 with Leaflet

Having some trouble trying to configure leaflet with the leaflet-markercluster plugin using angular 2. Although I've managed to make it work with angularJS in the past, I'm facing issues in angular and could use some guidance on what might be cau ...

When working with Typescript, you can declare an interface and split its definition across multiple files

I've been developing a software application that utilizes WebSocket with the NodeJS ws package. My networking structure revolves around a module responsible for handling message reception and transmission. Given that I'm working with TypeScript, ...

What is the best way to pass updates from input model class in a child component to its parent in Angular 13?

What is the best way to propagate changes in the input model class from a child component to its parent in Angular 13? Child Component export class ChildComponent implements OnInit { @Input() mdlInData: any; @Output() mdlOutData = new EventEmitter< ...

Properly passing props to child components in React with TypeScript. Resolve Error ts(2322)

I am facing an issue where my code works perfectly in Javascript, but encounters problems when converted to Typescript. Despite the complexity of the question, it actually boils down to a simple query. I just wanted to share the functional JS code as a sol ...

What could be the reason for the absence of a TypeScript error in this situation?

Why is it that the code below (inside an arbitrary Class) does not show a TypeScript error in VSCode as expected? protected someMethod (someArg?: boolean) { this.doSomething(someArg) } protected doSomething (mustBePassedBoolean: boolean) { /* ... * ...

evaluate a utility function that operates on children

In managing a component that requires children (referred to as the layout component), there is a specific function nested within this component that processes these child components. Testing this function poses a challenge, so I decided to extract it into ...

Challenges arise when trying to access environment variables using react-native-dotenv in React

I am currently working on two separate projects, one being an app and the other a webapp. The app project is already set up with react-native-dotenv and is functioning as expected. However, when I attempt to use the same code for the webapp, I encounter an ...

Using TypeScript and the `this` keyword in SharePoint Framework with Vue

I'm currently developing a SharePoint Framework web part with Vue.js. Check out this code snippet: export default class MyWorkspaceTestWebPart extends BaseClientSideWebPart<IMyWorkspaceTestWebPartProps> { public uol_app; public render(): ...

Implement a class in Typescript that allows for the addition of properties at runtime

I'm currently in the process of incorporating Typescript definitions into an existing codebase that utilizes the Knockout library. Within the code, there is a prevalent pattern that appears as follows: interface SomeProperties { // Assorted prope ...

Suggestions for enhancing or troubleshooting Typescript ts-node compilation speed?

Recently, I made the switch to TypeScript in my codebase. It consists of approximately 100k lines spread across hundreds of files. Prior to the migration, my launch time was an impressive 2 seconds when using ESLint with --fix --cache. However, after impl ...

Secure your React TypeScript applications with GraphQL authentication

When users try to log in on my website, I need to verify their authentication using data from a GraphQL API. I referred to this tutorial for guidance: https://www.apollographql.com/docs/react/networking/authentication/ In my GraphQL playground, I execute ...

Exploring the Secrets of JSON Parsing in Angular

In my Angular application, I have the following JSON: var alphas = { "Data": { "1" : { "abc": { "key1":"Value1", "key2":"Value2", ...

Is there a way for me to define the type of a prop based on the type of another prop?

I'm not entirely certain how to phrase this inquiry, or which terminology to employ, so I'll do my best in presenting it. My intention is to develop a component that functions on an array of elements and triggers a render function for each eleme ...

How can I establish a connection to a Unix socket path using a connection string with Slonik?

Hey there! I encountered an issue while attempting to connect to a Google Cloud database using slonik: const pool = createPool( `socket:userName:password@/cloudsql/teest-123986:europe-west3:test?db=dbName` ) The error message I received was: error: throw ...

Subscribing to events in Angular 2 after switching tabs and returning to the

I have a Subject service implemented as follows; private subject = new Subject<any>(); sendMessage(message: any) { this.subject.next(message); } clearMessage() { this.subject.next(); } getMessage(): Observable<any> { return this ...