Eneko
Eneko

Reputation: 2117

How to detect you were routed by history back?

I have a component which state should be different depending if the user went back in history (pushed left arrow button) or went to route directly.

Is there a way to query the router if route change was fired by one way or the other?

At this time I get it tampering with location.url but I look for a more elegant way.

Upvotes: 1

Views: 2652

Answers (1)

Chris Hamilton
Chris Hamilton

Reputation: 10994

TLDR: A combination of the LocationStrategy service and a custom shared service.

https://stackblitz.com/edit/angular-ivy-fvh3gm?file=src/app/one/one-state.service.ts

Stackblitz's back button does not work like a normal browser so I use an html button and the history.back() function in the example. I've tested this in an actual browser and it works just the same with the native back button.


Make a service to handle the component's state from anywhere in your application. Use the LocationStrategy service and create a callback for when the back button is pushed using onPopState(). Check that the current path matches the component's path using path(). If so, set a boolean variable.

Since services are singleton, the constructor will only be called when the service is injected for the first time. In this case, it will be called when we first open the component, so this is a great place to attach our callback. I've used the names OneComponent and OneStateService in my example.

export class OneStateService {
  path = '/one';
  navigatedBack = false;

  constructor(private location: LocationStrategy) {
    this.location.onPopState(() => {
      if (this.location.path() === this.path) this.navigatedBack = true;
    });
  }
}

Inject the service into your component, make sure to set the value back to false in ngOnDestroy

export class OneComponent implements OnDestroy {
  constructor(private router: Router, public state: OneStateService) {}

  ngOnDestroy() {
    this.state.navigatedBack = false;
  }

  goToTwo() {
    this.router.navigate(['two']);
  }
}

Now use the service's variable to conditionally change the component.

<button (click)="goToTwo()">Go To Component Two</button>
<br />
<br />
<p *ngIf="state.navigatedBack">You came back!</p>

Upvotes: 3

Related Questions