Events are a key-form of communication in a multi-component application. A good event-driven architecture can save your application from turning into a maintenance nightmare. While Svelte allows event forwarding for standard DOM events, we also need to use custom events from time to time. In this post, we will learn how to create custom events in Svelte using createEventDispatcher().

1 – CreateEventDispatcher in Svelte

Components in Svelte can dispatch events. However, to do so, they need to use createEventDispatcher().

Basically, this is a utility provided as part of Svelte.

See below example of how to use the event dispatcher in a Svelte component.

<script>
    import { createEventDispatcher } from 'svelte';

    let dispatch = createEventDispatcher();

    let title;
    let author;

    const addBook = () => {
        const book = {
            id: Math.random(),
            title,
            author
        }
        dispatch('addBookEvent', book)
    }
</script>

<form on:submit|preventDefault={addBook}>
    <input type="text" placeholder="title" bind:value={title}>
    <input type="text" placeholder="author" bind:value={author}>
    <button>Add Book</button>
</form>

This is a very simple component. Basically, it has a form that allows the user to input the title of the book and the name of the author.

When the form is submitted by clicking the AddBook button, the addBook() function is triggered. Within the function, we create a book object and use dispatch() function to dispatch an event with name addBookEvent. We pass the book object as the event payload.

The dispatch() function is available from the call to createEventDispatcher().

2 – Handle the Custom Event

Once the event is created in a particular component, another component has to handle the event. In this case, we want Svelte to dispatch event to the parent component. The parent component is the App component where we will handle the event

See below:

<script>
	import Modal from './Modal.svelte'
	import AddBookForm from './AddBookForm.svelte'

	export let name;

	let showModal = false;
	let books = [];

	const toggleModal = () => {
		showModal = !showModal;
	}

	const addBook = (event) => {
		const book = event.detail;
		books = [book, ...books];
		showModal = false;
	};
</script>

<Modal showModal={showModal} on:click={toggleModal}>
	<AddBookForm on:addBookEvent={addBook}/>
</Modal>
<main>
	<h1>Hello {name}!</h1>
	<button on:click={toggleModal}>Show Modal</button>
	{#each books as book (book.id)}
		<div>
			<h4>{book.title} - {book.author}</h4>
		</div>
	{/each}
</main>

Here, we use the AddBookForm component and bind on:addBookEvent to the same along with specifying the handler function. Here, the handler function is addBook().

Basically, this works the same way as any other event such as on:click or on:submit. However, instead of events that are part of Svelte, we are binding to our own custom event.

The addBook() function receives the event object as the input argument. We extract the payload which is available as part of the event object and add it to the books array. Also, we render the data in the books array using an each block.

Notice that we don’t use the Javascript push() function to update the books array. This is because Svelte’s Reactivity is triggered only by assignment operation.

Below is the Modal component code for reference.

<script>
    export let showModal = false;
    let isInteresting = false;
</script>

{#if showModal}
    <div class="backdrop" class:interesting={isInteresting} on:click|self>
        <div class="modal">
            <slot></slot>
        </div>
    </div>
{/if}

Basically, this is a simple component with <slot> to inject the Book form. You can read more about slots in our detailed post on Svelte slots.

If we run the application now, we can see our custom event in action.

svelte custom events

We add a book in the form. On clicking the Add Book button, the book details are available in the parent component.

Conclusion

With this, we are done with creating Svelte custom events using createEventDispatcher() function.

If you have any comments or queries about this post, please feel free to mention in the comments section below.

Categories: Svelte

0 Comments

Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *