Last Updated: February 25, 2016
· iaincampbell

Custom event listeners in Polymer Dart

It's straightforward to listen for an event on a custom element in Polymer:

<my-element on-buttonclicked='{{doAction}}'></my-element>

And my-element.dart:

clicked(Event e) {
    dispatchEvent(new CustomEvent('buttonclicked', detail:  { 'this': 'that', 'and': 'this' });

Then in the code-behind file:

doAction(Event e, var detail, Node target) {

But what happens if your code-behind is elsewhere in the DOM hierarchy and you add my-element programmatically? You can't bind using an attribute, so the first thing you try is:

var element = new Element.tag('my-element');
element.addEventListener('buttonclicked', doAction);

No-go, I'm afraid. You need import dart:async and use an EventStreamProvider like so:

static const EventStreamProvider<CustomEvent> buttonClickedEvent = 
  const EventStreamProvider<CustomEvent>("buttonclicked");

Stream<CustomEvent> get onButtonClicked =>  MyElement.buttonClickedEvent.forTarget(this);

Then attaching your event to your element becomes a case of:

var element = new Element.tag('my-element');
element.onButtonClicked.listen((e) => doAction(e));