Skip to content

Url Histroy Service angular 19

ts
import { Location } from '@angular/common';
import { effect, inject, Injectable, signal } from '@angular/core';
import { NavigationEnd, Router } from '@angular/router';
import { LocalstorageService } from './localstorage.service';

@Injectable({
  providedIn: 'root',
})
export class UrlService {
  public readonly history = signal<string[]>([]);
  public retainLength = signal<number>(Number.MAX_SAFE_INTEGER);
  private router = inject(Router);
  private _location = inject(Location);
  private _localstorageService = inject(LocalstorageService);
  private _localestorageKey = 'url-history';
  
  #_persist = effect(() => {
    let _oldQueu =
      this._localstorageService.get<string[]>(this._localestorageKey) || [];
    const newOne =
      this.history().length > 0
        ? [this.history()[this.history().length - 1]]
        : [];

    if (_oldQueu.length === 0) {
      this._localstorageService.set<string[]>(this._localestorageKey, [
        ..._oldQueu,
        ...newOne,
      ]);
      return;
    }

    _oldQueu = _oldQueu.slice(-this.retainLength());

    // avoid duplicates
    if (_oldQueu[_oldQueu.length - 1] === newOne[0]) {
      return;
    }
    this._localstorageService.set<string[]>(this._localestorageKey, [
      ..._oldQueu,
      ...newOne,
    ]);
  });

  constructor() {
    this.history.set(
      this._localstorageService.get<string[]>(this._localestorageKey) || []
    );
    this._hookOnRouterEvents();
    this._hookOnLocationEvents();
  }

  _hookOnRouterEvents() {
    this.router.events.subscribe((event) => {
      if (event instanceof NavigationEnd) {
        if (
          this.history().length > 0 &&
          this.history()[this.history().length - 1] === event.url
        ) {
          return;
        }
        this.history.set([...this.history(), event.url]);
      }
    });
  }

  _hookOnLocationEvents() {
    this._location.onUrlChange((url) => {
      if (
        this.history().length > 0 &&
        this.history()[this.history().length - 1] === url
      ) {
        return;
      }
      this.history.set([...this.history(), url]);
    });
  }

Usage

ts
export class MyComponent {
  ...
  private _urlService = inject(UrlService);

  async myAsyncFunction() {
    const urlToGo = this._urlService.history();

    ...
  }
}