# Firing event from custom element only when value changes

**URL:** <https://discourse.aurelia.io/t/firing-event-from-custom-element-only-when-value-changes/669>\
**Category:** Help Requests\
**Created:** [January 19, 2018, 4:14pm UTC](https://discourse.aurelia.io/t/firing-event-from-custom-element-only-when-value-changes/669 "2018-01-19T16:14:58Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![jeremyholt](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/jeremyholt/32/1098_2.png) [@jeremyholt](https://discourse.aurelia.io/u/jeremyholt)\
**Post date:** [January 19, 2018, 4:14pm UTC](https://discourse.aurelia.io/t/firing-event-from-custom-element-only-when-value-changes/669/1 "2018-01-19T16:14:58Z")

</div>

What I am trying to achieve is to get the changed event to fire only when the new value has changed. With the control below, the changed event fires twice - once with the current value and then a second time with the new value.

```auto
<template>
  <div class="input-group">
    <div class="input-group-prepend">
      <span class="input-group-text">${label}</span>
    </div>
    <div class="d-inline">
      <select class="custom-select w-100" value.bind="value">
        <option if.bind="showOption">[${label}]</option>
        <option repeat.for="item of datasource" model.bind="item">${item.name}</option>
      </select>
    </div>
  </div>
</template>

```

```auto
import { autoinject, bindable, bindingMode } from "aurelia-framework";
import {TaskQueue} from "aurelia-framework";

@autoinject
export class FormSelectControl {
  @bindable public label = "Select";
  @bindable({ defaultBindingMode: bindingMode.twoWay }) public value;
  @bindable public datasource;
  @bindable public showOption = false;

  constructor(private readonly element: Element, private readonly taskQueue: TaskQueue) {
  }

  public valueChanged(newValue) {
    const evt = new CustomEvent("change", {
      bubbles: true,
      detail: newValue
    });

    this.taskQueue.queueMicroTask(() => {
      this.element.dispatchEvent(evt);
    });
  }
}

```

I’ve tried the obvious things such as

```auto
if(newValue !== oldValue) {
...
this.element.dispatchEvent(evt);
...
}

```

but the event never fires.

In the view

```auto
<form-select-control label="Select something" datasource.bind="myDataList" value.bind="selectedItem" change.delegate="onSelectedItemChanged($event)"></form-select-control>

```

and in the model

```auto
public onSelectControlChanged(){
   this.loadDataFromServer(this.selectedItem.id);
// check selectedItem is the new data
}

```

It is here that I need to check that the `selectedItem` has changed, otherwise it hits the server for the data is currently in the viewModel and then again for the `new` value of the selectedItem.

---

<div class="post-metadata">

**Author:** ![jeffgrann](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/jeffgrann/32/43_2.png) [@jeffgrann](https://discourse.aurelia.io/u/jeffgrann)\
**Post date:** [January 19, 2018, 5:19pm UTC](https://discourse.aurelia.io/t/firing-event-from-custom-element-only-when-value-changes/669/2 "2018-01-19T17:19:08Z")

</div>

How about using `observable` on `selectedItem` instead of triggering events?

GistRun example: [https://gist.run/?id=ff8fc7f2844345c9e34186226041d4ca](https://gist.run/?id=ff8fc7f2844345c9e34186226041d4ca)

Simplified ES6 code:

**form-select-control.html**

```
<template>
  <select value.bind="value">
    <option repeat.for="item of datasource" model.bind="item">${item.name}</option>
  </select>
</template>

```

**form-select-control.js**

```
import {bindable, bindingMode} from 'aurelia-framework';

export class FormSelectControl {
  @bindable({ defaultBindingMode: bindingMode.twoWay }) value;
  @bindable()datasource;
}

```

**app.html**

```
<template>
  <require from="./form-select-control"></require>
  <form-select-control datasource.bind="myDataList" value.bind="selectedItem"></form-select-control>
</template>

```

**app.js**

```
import { observable } from 'aurelia-framework';

export class App { 
  @observable()selectedItem;
  myDataList = [{name: "Jerry"}, {name: "George"}];
  
  selectedItemChanged(newValue, oldValue) {
    if (newValue.name !== oldValue.name) {
      alert(`new: ${JSON.stringify(newValue)} old: ${JSON.stringify(oldValue)}`);
    }
  }
}
```

---

<div class="post-metadata">

**Author:** ![vegarringdal](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/vegarringdal/32/248_2.png) [@vegarringdal](https://discourse.aurelia.io/u/vegarringdal)\
**Post date:** [January 19, 2018, 6:04pm UTC](https://discourse.aurelia.io/t/firing-event-from-custom-element-only-when-value-changes/669/3 "2018-01-19T18:04:25Z")

</div>

@jeffgrann nice post 😄

---

<div class="post-metadata">

**Author:** ![jeremyholt](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/jeremyholt/32/1098_2.png) [@jeremyholt](https://discourse.aurelia.io/u/jeremyholt)\
**Post date:** [January 20, 2018, 8:21pm UTC](https://discourse.aurelia.io/t/firing-event-from-custom-element-only-when-value-changes/669/4 "2018-01-20T20:21:55Z")

</div>

Thank you - I’d never realized how observable works 😁

---

<div class="post-metadata">

**Author:** ![dmbarth](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/dmbarth/32/913_2.png) [@dmbarth](https://discourse.aurelia.io/u/dmbarth)\
**Post date:** [July 29, 2019, 7:33pm UTC](https://discourse.aurelia.io/t/firing-event-from-custom-element-only-when-value-changes/669/5 "2019-07-29T19:33:09Z")

</div>

For those who are visiting this discussion topic looking for why the event is firing twice, it’s because the original event is bubbling and then you are firing off another. To handle changes on your custom element, all you would need to do is add a `change.delegate` on the custom element and it will catch the bubbling event.

Additionally, you may be binding the value of a model that is not observable. Handling the change event is helpful in these situations.
