6

I'm trying to set a flag in my component to know if the view is loaded by the user clicking on the "Previous page" button of the browser.

The "fromBackButton" attribute is set to false when is defined in the component.

In the constructor I have this code:

this.location.subscribe((popStateEvent: PopStateEvent) => {
  // Detect popstate
  if (popStateEvent.type === 'popstate') {
    this.fromBackButton = true;
  }
});

If I put console.log(this.fromBackButton) in the ngOnInit or in any other method, the value is False.

I've tried using

this.changeDetectorRef.markForCheck();

and

this.changeDetectorRef.detectChanges();

after setting the flag to "True", and also tried to use ngZone.run(), but I get the same result

p0kero
  • 120
  • 1
  • 1
  • 12

1 Answers1

2

The problem is that the component is reinitialized when navigating. So, the fromBackButton field is set to true on navigating back and immediately reset to false on new component initialization.

So you need to create a service to get something that "survives" the navigation cycle. I mean something like this (StackBlitz here):

export class NavigationStateService implements OnDestroy {
  private _isFromBackButton = false;

  private locationSubscription: SubscriptionLike;

  constructor(private location: Location) {
    this.locationSubscription = this.location.subscribe((popStateEvent: PopStateEvent) => {
      // Detect popstate
      if (popStateEvent.type === 'popstate') {
        console.debug('fromBackButton NavigationStateService', popStateEvent);
        this._isFromBackButton = true;
      }
    });
  }

  get isFromBackButton(): boolean {
    return this._isFromBackButton;
  }

  clearFromBackButtonState() {
    this._isFromBackButton = false;
  }

  ngOnDestroy(): void {
    this.locationSubscription.unsubscribe();
  }
}

The corresponding component example:

export class Page1Component implements OnInit {
  fromBackButton = false;

  constructor(private navigationStateService: NavigationStateService) { }

  ngOnInit(): void {
    this.fromBackButton = this.navigationStateService.isFromBackButton;
    this.navigationStateService.clearFromBackButtonState();
  }
}

But here comes the fly in the ointment of the PopState Event: It is fired equally on forward and backward navigation. But that's another task. A good starting point for this maybe here: How do I retrieve if the popstate event comes from back or forward actions with the HTML5 pushstate?

Mike Feustel
  • 1,277
  • 5
  • 14