0

I have a controller in my ember 2.18 app and I want to make it listen to some event myEventName triggered somewhere in the app, to change the model properties.

According to the API docs for this version the way to catch an emitted event is like this:

import Evented from '@ember/object/evented';
import Controller from '@ember/controller';
// extend some object, like a Controller
const myExtendedObject = Controller.extend(Evented, { 
    // stuff ...
     });

myExtendedObject.on('myEventName', function (args) {  
    console.log("catch importDone  ok", args); 
    });
export default myExtendedObject;

the code compiles well with ember build dev, but in the browser's JS console I get this error message:

Error: Assertion Failed: on called without valid event names error.js:40

I tried renaming event, but I cannot find why the event name is wrong. I also tried to set three arguments to the on method, but it is still bugging with the event name. What am I missing?

Edit:
I made an Ember twiddle showing that events are scoped to components. I would like to catch them from anywhere; like triggering an event from a Service and catch it in a Route.

https://ember-twiddle.com/ce22cc0a542e8e0997a1ad57a4a9688c?fullScreen=true

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Ty Kayn
  • 719
  • 7
  • 24

1 Answers1

1

You can use it like this:

import { on } from '@ember/object/evented';

export default Controller.extend(Evented, {
  init() {
    this._super(...arguments);
    this.trigger('greet');
  },

  myGreetImplementation: on('greet', function() {
    console.log('hello');
  })
});

Another example: Using a service to manage the user settings and subscribing to changes:

export default Service.extend(Evented, {
  ...
  changeProfilePicture() {
    ...
    this.trigger('profilePictureChanged', ... event parameters ...);
  }
});

Then you could watch for such event anywhere using the on method:

 export default Controller.extend({
  userSettings: service(),

  init() {
    this._super(...arguments);
    this.get('userSettings').on('profilePictureChanged', this, this.profilePictureChanged);
  },

  profilePictureChanged(... event parameters ...) {
   ...
  }
});

There error you get is coming from here: https://github.com/emberjs/ember.js/blob/6fc89cdf13124d88b8ae6adf99bb02a8c0cdf508/packages/ember-metal/lib/events.ts#L211 (You can just paste error messages in the github search or use the debugger to find out more about why something is failing)


Update: Extending your twiddle to have the Controller register on the service's event:

import Ember from 'ember';
import { inject as service } from '@ember/service';
import { on } from '@ember/object/evented';

export default Ember.Controller.extend({
  appName: 'Ember Twiddle',
  myService: service(),
  init() {
    this._super(...arguments);
    this.get('myService').on('mycall', this, this.mycallHandler);
  },
  mycallHandler: on('mycall', function() {
    console.log('here we are');
  })
});
enspandi
  • 663
  • 4
  • 6
  • thank for the examples. but i dont find a way to make the emitted events to be catched outside their own service/component/controller. which makes it not very useful. in my case i have a TransferService which triggers and event "timeToReloadFile" when a user has succefully uploaded some files. but the documentListController, which listens on that event never catches it. no idea why. – Ty Kayn Aug 20 '18 at 13:17
  • 1
    Yeah, the events are tied to an Ember.Object (Component, Controller, Service etc.). So if you need something like a global event bus, you could have a service called like that and trigger and register events there... You might want to checkout: https://github.com/blia/ember-cli-events-bus/ All that's necessary: https://github.com/blia/ember-cli-events-bus/blob/master/addon/services/events-bus.js The other file https://github.com/blia/ember-cli-events-bus/blob/master/addon/initializers/events-bus.js is just taking care that you don't have to register this service every time. – enspandi Aug 20 '18 at 15:26