svelteaddeventlistenerserver-sent-eventsremoveeventlistener

Is there a way to simplify this code avoiding to call `onDestroy` manually each time?


We're using EventSource in multiple places in out SvelteKit app, like this:

<script>
  import { onDestroy } from 'svelte';
  import { customEventSource } from '$lib/events';

  const callback = (event: MessageEvent) => {
    console.log('event:', event);
  };

  customEventSource.addEventListener('message', callback);

  onDestroy(() => {
    customEventSource.removeEventListener('message', callback);
  });
</script>

As you can see there is a lot to write each time.

Isn't there a magic way - as Svelte has taught us - to simplify?

Especially so I don't have to manually call onDestroy every time?


Solution

  • I imagine something like this will work:

    // This is a helper file.
    
    import { onDestroy } from 'svelte'
    import { customEventSource } from '$lib/events'
    
    export function listenForMessages(listener){
       customEventSource.addEventListener('message', listener)
       onDestroy(() => customEventSource.removeEventListener('message', listener))
    }
    

    In your component:

    <script>
    import { listenForMessages } from './the-file.js'
    
    listenForMessages((event) => {
       console.log('event:', event)
    })
    </script>