skip to Main Content

I have created an angular service which can listen to cookie changes by leveraging the CookieStore Api.
My current code looks as follows:

type CookieChangeType = {
    name: string,
    value: string,
    expires: Date,
    domain: string,
}

interface CookieChangeEvent extends Event {
    changed: CookieChangeType[]
}

type CookieStore = {
    addEventListener: Window["addEventListener"]
}

declare global {
    interface Window {
        cookieStore: CookieStore;
        addEventListener(type: String, listener: (this: Window, ev: CookieChangeEvent) => any, useCapture?: boolean): void;
    }
} 

export class CookieConsentCommonsService {
     
    
    subscribeToConsentCookieChange(callback: () => void): void {
            window.cookieStore.addEventListener('change', (event: CookieChangeEvent) => {
                console.log(`Cookie changed: ${change.name} = ${change.value}`);
                callback();            
            });
    }
}

This code works as expected.
On the top of that I would like to be able to cancel the subscription. I have tried to store the subscription for later :

            const sub = window.cookieStore.addEventListener( ...);
            console.log("sub " + sub)

But there is no return from this code and the output message is:

sub undefined

How can I retrieve a reference for created subscription and later on use it to cancel the subscription?

2

Answers


  1. https://developer.mozilla.org/zh-CN/docs/Web/API/EventTarget/removeEventListener

    function handleChange() {
      // ...
    }
    
    // sub
    window.cookieStore.addEventListener('change', handleChange);
    // unsub
    window.cookieStore.removeEventListener('change', handleChange);
    

    or

    const controller = new AbortController();
    
    // sub
    window.cookieStore.addEventListener('change', handleChange, { signal: controller.signal });
    // unsub
    controller.abort();
    

    ts

    // Cookie interface definition
    interface Cookie {
      name: string;
      value: string;
      expires?: Date | null; // Optional expiration time
      path?: string; // Optional path
      domain?: string; // Optional domain
      secure?: boolean; // Optional secure flag
      sameSite?: 'lax' | 'strict' | 'none'; // Optional SameSite attribute
    }
    
    // CookieStore interface inheriting from EventTarget
    interface CookieStore extends EventTarget {
      get(name: string): Promise<Cookie | null>;
      getAll(): Promise<Cookie[]>;
      set(cookie: Cookie): Promise<void>;
      delete(name: string): Promise<void>;
    }
    
    // Adding CookieStore to the global window object
    declare global {
      interface Window {
        cookieStore: CookieStore;
      }
    }
    
    Login or Signup to reply.
  2. You can try the rxjs way of handling events using fromEvent, I use takeUntilDestroyed to destroy the observable stream when the component is destroyed.

    cookieStore = (window as any)['cookieStore'];
    listener = (callback: () => void, event: any) => {};
    destroy$ = inject(DestroyRef);
    ngOnInit() {
      this.subscribeToConsentCookieChange(() => {});
    }
    
    async subscribeToConsentCookieChange(callback: () => void) {
      fromEvent<any>(this.cookieStore, 'change')
        .pipe(takeUntilDestroyed(this.destroy$))
        .subscribe((event: any) => {
          console.log(`Cookie changed: `, event);
          callback();
        });
      // this.cookieStore.addEventListener('change', (event: any) => {
      //   console.log(`Cookie changed`);
      //   callback();
      // });
      await this.cookieStore.set('test', 'asdf');
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search