2

I'm trying to figure out how to use this._super when the Ember's object method is called from a callback.

I know that I could assign var _super = this._super before the callback is called but I don't like it.

I want to have the this object containing proper _super method inside the callback.

My code is here: http://emberjs.jsbin.com/hasehija/6/edit.

App.BaseMixin = Ember.Mixin.create({
  init: function() {
    console.log("base");
  }
});

App.Utils = Ember.Object.extend({
  callbackMethod: function(callback, ctx) {
    // asynchronous callback
    Ember.run(function() {
      callback.call(ctx);
    });
  }
});

App.MyObject = Ember.Object.extend(App.BaseMixin, {
  init: function() {
    console.log("MyObject");
    var _super = this._super;
    App.Utils.create().callbackMethod(function() {
      this._super(); // this._super is undefined here
      // _super() would work
    }, this);
  }
});

App.ApplicationController = Ember.Controller.extend({
  init: function() {
    new App.MyObject();
  }
});

Do you know any way to fix it?


UPDATE:

It turned out that it was fixed in Ember 1.5.0 (@GJK: thank you for the answer) and I was using Ember 1.4.0.

andrusieczko
  • 2,824
  • 12
  • 23
  • In your jsbin I'm only getting an error that `App.Utils.callbackMethod` is undefined, not that `this._super` would not work? – Bergi Jun 10 '14 at 15:27
  • Yes I also am getting that your code is not working... Because the callback method is an instance method not a static one, so you would need to create an instance of this. Anyways though, why not just create a reference to `this` with `var self = this` at the top of your init method. Then you will still have access to everything on that object not just the super function. – bmeyers Jun 10 '14 at 15:58
  • 1
    It should be noted that if you plan to call `this._super()` asynchronously, it won't work. [Ember 1.5.0](http://emberjs.com/blog/2014/03/30/ember-1-5-0-and-ember-1-6-beta-released.html#toc_ever-present-_super-breaking-bugfix) changed that. – GJK Jun 10 '14 at 16:35
  • Honestly, it's recommended that you don't override `init`, if you want to do something on init you should create a method, and tack on `on('init')` (example added below) – Kingpin2k Jun 10 '14 at 16:41

1 Answers1

2

extend defines a class

App.Utils = Ember.Object.extend({
  callbackMethod: function(callback, ctx) {
    callback.call(ctx);
  }
});

create builds an instance of the class

App.Utils = Ember.Object.create({
  callbackMethod: function(callback, ctx) {
    callback.call(ctx);
  }
});

or

App.Utils.create().callbackMethod(function() {
  this._super(); 
}, this);

http://emberjs.jsbin.com/hasehija/7/edit

Or avoid overriding init

App.ApplicationController = Ember.Controller.extend({
  doSomething: function() {
    new App.MyObject();
  }.on('init')
});
Kingpin2k
  • 47,277
  • 10
  • 78
  • 96
  • Hi, thanks. Obviously I did a mistake in the provided code. I could do either `App.Utils.create()` or `new App.Utils()` but that's not the point. It appeared that the issue was fixed in Ember 1.5.0 as @GJK mentioned. – andrusieczko Jun 11 '14 at 03:11
  • 1
    I don't understand, 1.5 was a breaking change, it wouldn't have fixed the issue you described. You never made a call back asynchronously. – Kingpin2k Jun 11 '14 at 03:28
  • Yes, you're obviously right. In the shown example I used the synchronous callback. In the real project I had a asynchronous callback. I was not aware that this is the true reason behind it. – andrusieczko Jun 11 '14 at 04:48