Inspecting previous page in Angular

June 10th 2022 Angular

You can use Angular Location service to implement programmatic backward navigation from non-root pages:

public onBack(): void {
  this.location.back();
}

However, if the user has used a non-root URL to navigate to your application, they will navigate out of the application in this way. You may want to detect this and navigate them back to the root page instead when this happens.

The only way to do this was to subscribe to the router events, as suggested in a Stack Overflow answer. Each time the user navigates, I log the origin URL and then check it before navigating back:

const HOME_URL = "/home";

@Injectable({
  providedIn: "root",
})
export class NavigationService {
  private previousUrl?: string;

  constructor(
    private readonly router: Router,
    private readonly location: Location
  ) {
    this.router.events
      .pipe(
        filter((event) => event instanceof RoutesRecognized),
        map((event) => event as RoutesRecognized),
        pairwise()
      )
      .subscribe((events: [RoutesRecognized, RoutesRecognized]) => {
        this.previousUrl = events[0].urlAfterRedirects;
      });
  }

  public back(): void {
    if (this.previousUrl !== undefined) {
      this.location.back();
    } else {
      this.router.navigate([HOME_URL], { replaceUrl: true });
    }
  }
}

On the entry page, the previous URL is not yet set. So instead of navigating back in the browser history, I use the Angular router to navigate to the root page. Also, I use replaceUrl to replace the entry in the browser history, so the user has no way to navigate back to their entry page from the root page.

On the non-root pages, I now use my service method to navigate back instead of using the Location service directly:

public onBack(): void {
  this.navigationService.back();
}

It's important to subscribe to events before any navigation occurs within the app. This means that the service needs to be initialized and thus injected into a component early enough. A good place to ensure this is the AppComponent:

export class AppComponent {
  constructor(navigationService: NavigationService) {}
}

You can see the full source code for a minimal working example in my GitHub repository.

The Angular Location service can be used to programmatically navigate back in the browser history. If you do not want the user to navigate out of your application this way, you need to detect this before navigating. In this post, I described a way to do that by subscribing to Angular router events.

Get notified when a new blog post is published (usually every Friday):

Copyright
Creative Commons License