Building Web Components 101 - Part 4
Tags: webcomponents, javascript
Published: 2022-09-26 04:52:56

Part 3 covers how to create custom attributes. Let's continue in this article on how to create custom events for our custom web components.

I will start with where we left off in Part 3. To access the source code in this article, you can clone the project at [https://github.com/tebinraouf/learning-fast/tree/building-web-components-101-part-4](https://github.com/tebinraouf/learning-fast/tree/building-web-components-101-part-4)


or you can use Stackblitz

{% embed https://stackblitz.com/github/tebinraouf/learning-fast/tree/building-web-components-101-part-4?file=index.html %}

We use attributes to send/pass data to the web component. Events are useful to get data or send data to the consumer of the web component so that they can use it to build application logic.

To create a custom event, there are two steps:
1. Identify the element in the web component template to receive the custom event.
2. Emit the event so that users can add the custom event and get any data. 

Here, we want to add `onClick` to the `h1` element so that every time we click, we send new data to the customer. In this case, when we click, we send back a new Albert Einstein quote. It's up to the user how to handle this new quote. In our example, we update the quote.

Steps in detail:
1. Update `h1.template.ts` and add an `onClick` event listener. In FAST, the syntax to add an event listener is `@click="${x => x.handler()}"` where `@click` is the event name, which is `onClick`, and `x.handler()` is the handler/controller on the element class, which will be defined in `h1.ts` where the custom element class is created.  


```diff
import { html } from "@microsoft/fast-element";


export const template = html`
-    <h1 style="color: ${x => x.color}">
+    <h1 style="color: ${x => x.color}" @click="${x => x.handler()}">
        <slot></slot>
    </h1>
```

2. Update `h1.ts` to include a private method `handler`. This could be any name. 

```ts
    private handler() {
        this.$emit('colorhandler')
    };
```

By doing so, now our web component consumer can add a custom event `colorhandler` to the web component like below:

We added an id to the custom element.
```html
<tebin-h1 color="blue" id="blue-title">Albert Einstein</tebin-h1>
```
We then use `addEventListener` to add a custom event, which is named `colorhandler`. 
```js
    <script>
        document.getElementById("blue-title").addEventListener('colorhandler', function (e) {
//business logic
        });
    </script>
```

## How to send data to the web element consumer?
In this example, we are randomly sending a new quote through our custom event `colorhandler`. To do so, when we `emit` the `colorhandler`, we send the data with it like below:

```ts
    private handler() {
        const quotes = ["We cannot solve our problems with the same thinking we used when we created them", "The true sign of intelligence is not knowledge but imagination.", "I have no special talent. I am only passionately curious.", "The only reason for time is so that everything doesn't happen at once.", "Only a life lived for others is a life worthwhile."];
        const random = Math.floor(Math.random() * quotes.length);

        this.$emit('colorhandler', quotes[random])
    };
```
The data can be anything. In this case, we send back a string.

Lastly, the web element consumer can get the quote through the event detail i.e. `e.detail` like below.

```html
    <script>
        document.getElementById("blue-title").addEventListener('colorhandler', function (e) {
            document.getElementById("ae-quote").innerText = e.detail;
        });
    </script>
```

Now, every time someone clicks on the custom web element title, the description changes with a new quote.


![A gif that shows different quotes](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8udzb5lyvx2eou4f9r80.gif)