How to pass parameters to on:click in Svelte?

TL;DR

Just wrap the handler function in another function. For elegancy, use arrow function.


You have to use a function declaration and then call the handler with arguments. Arrow function are elegant and good for this scenario.

WHY do I need another function wrapper?

If you would use just the handler and pass the parameters, how would it look like?

Probably something like this:

<button on:click={handleClick("arg1")}>My awesome button</button>

But remember, handleClick("arg1") this is how you invoke the function instantly, and that is exactly what is happening when you put it this way, it will be called when the execution reaches this line, and not as expected, ON BUTTON CLICK...

Therefore, you need a function declaration, which will be invoked only by the click event and inside it you call your handler with as many arguments as you want.

<button on:click={() => handleClick("arg1", "arg2")}>
    My awesome button
</button>

As @Rich Harris (the author of Svelte) pointed out in the comments above: This is not a hack, but is what the documentation shows also in their tutorials: https://svelte.dev/tutorial/inline-handlers


Rich has answered this in a comment, so credit to him, but the way to bind parameters in a click handler is as follows:

<a href="#" on:click|preventDefault={() => onDelete(projectId)}>delete</a>

function onDelete (id) {
  ...
}

To provide some extra detail for people who also struggle with this, and it should be in the docs if it isn't, you can also get the click event in such a handler:

<a href="#" on:click={event => onDelete(event)}>delete</a>

function onDelete (event) {
  // if it's a custom event you can get the properties passed to it:
  const customEventData = event.detail

  // if you want the element, you guessed it:
  const targetElement = event.target
  ...
}

I got it working with this:

<a href="#" on:click|preventDefault={onDelete.bind(this, project_id)}>delete</a>

function onDelete(id) {
}