Angular back button with query parameter state in reusable component

1.1k views Asked by At

So in my angular layout component i've had a back button that's being used for all components

<div class="wrapper-class">
    //this is the back button that is displayed on every page
    **<app-back-button></app-back-button>**

    <div class="container-class">
        <router-outlet></router-outlet>
    </div>
</div>

In the back button component i could just use the function location.back() from Location in '@angular/common'

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

Now i have added pages with a search function and paging. So let's say the user is on a product overview page and enters a keyword in the search box and navigates to page 2 on the product overview page and selects an item and navigates to the details page. When the user decides to navigate back to the product overview page, the user would like the searched text and previous page number to be restored.

location.back() will navigate back to the product overview page but will lose it's state.

I've come across another solution below.

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

@Component({
  selector: 'app-back-button',
  templateUrl: './back-button.component.html',
  styleUrls: ['./back-button.component.scss']
})
export class BackButtonComponent implements OnInit {
  private previousUrl: string = undefined;
  private currentUrl: string = undefined;
  private paramsObject: any;

  constructor(
    private router: Router,
    private activatedRoute: ActivatedRoute,
    private location: Location
  ) { }

  ngOnInit(): void {
    this.currentUrl = this.router.url;

    this.router.events.subscribe(event => {
      if (event instanceof NavigationEnd) {
        this.previousUrl = this.currentUrl;
        this.currentUrl = event.url;
      };
    });

    this.activatedRoute.queryParamMap.subscribe((queryParams) => {
      this.paramsObject = { ...queryParams };
    });
  }

  goBack = () => {
    var url = this.previousUrl?.split('?')[0]

    if (!url) {
      this.location.back();
    }

    if (url?.includes('?') || !this.paramsObject?.params) {
      this.router.navigate([url]);

      return;
    }

    this.router.navigate([url], { queryParams: this.paramsObject?.params });
  }
}

However this won't work with all situations.

Situation 1 works perfectly: user navigates to component 1 then to component 2, presses the back button and will navigate back to component 1 with it's previous state intact.

Situation 2 doesn't work: User navigates to component 1 then to component 2 and the to component 3. The user presses the back button and will navigate to component 2, the user presses the back button again to go back to component 1 but will return to component 3 instead, since component 3 is now the previous URL.

location.back() is the perfect function if it would only keep track of state. Is it even possible to use a single component that navigates to the previous page with the query parameters state intact? It seems like a commonly used functionality.

0

There are 0 answers