1

I'm wrapping a JS component into an Ember Addon, something I've done many times before, and yet I'm running into a problem right at the get-go that makes me worry that maybe the "magic" of ember has shifted slightly? Anyway hoping can explain why the following:

import Ember from 'ember';
import layout from '../templates/components/nav-menu';

export default Ember.Component.extend({
  layout: layout,
    tagName: 'nav',
  classNames: ['navmenu','navmenu-default','navmenu-fixed-left'],
  attributeNames: ['role:navigation'],
  classNameBindings: ['offcanvas'],
  hideAt: null,
  offcanvas: function() {
    let hideAt = this.get('hideAt');
    if(!hideAt) {
      return 'offcanvas';
    } else {
      return 'offcanvas-%@'.fmt(hideAt);
    }
  }.property('hideAt'),

  _initialize: function() {
    this.$().offcanvas();
  }.on('didInsertElement')
});

This fails on two counts. As-is it fails in the offcanvas computed property saying:

Uncaught TypeError: undefined is not a function

Very odd but it gets odder. If remove this computed property it then fails at the _initialize() call with the same "undefined is not a function" error:

I'm using Ember 1.11.0, Ember-CLI 0.2.2.

ken
  • 8,763
  • 11
  • 72
  • 133
  • Do you happen to have prototype extensions disabled? – GJK Apr 01 '15 at 18:15
  • I created a brand new "addon" with just this component and got the same result. I wonder if something's off with Ember-CLI 0.2.2 :( – ken Apr 01 '15 at 18:35
  • It definitely feels like prototype extensions are getting blocked but I haven't turned them off. – ken Apr 01 '15 at 18:41

1 Answers1

5

You're right in this is related to Ember CLI 0.2.2. From the changelog:

Addons now have ember-disable-prototype-extensions included by default, this ensures add-ons are written in a way that works regardless of the consumers prototype extension preference.

I see their reasoning behind the change and it makes total sense. You will now need to use Ember.computed and Ember.on to create your properties and observers. So these:

initialize: function() {}.on('didInsertElement'),
offcanvas: function() {}.property('hideAt')

Become these:

initialize: Ember.on('didInsertElement', function() {}),
offcanvas: Ember.computed('hideAt', function() {})

You can read more about disabling prototype extensions here.

GJK
  • 37,023
  • 8
  • 55
  • 74
  • thanks, i was pulling my hair out on this one ... just getting off of 3 days of a nasty flu and thought maybe I had lost my mind during the process :) – ken Apr 01 '15 at 18:44
  • @glk I think the approach makes sense but even after moving away from use of prototype extensions the dummy test application is giving me some pretty hard to debug errors that I suspect are down to this change as well. – ken Apr 01 '15 at 20:50
  • as an example, the same "undefined is not a function" effects ember-debug's source map's `sourceMapCache` computed property. – ken Apr 01 '15 at 20:57
  • My suggestion would be to turn prototype extensions back on (for now). Most addons out there are going to be using them, so if you're using your addon along with others, you'll run into issues. However, I'd suspect that most popular addons will be updated within just a couple of weeks, at which point you should be able to turn it back off. (Also, just FYI the `.fmt()` function won't work with extensions disabled.) – GJK Apr 01 '15 at 20:59
  • Ahh good catch on fmt. Maybe it's time for ES6 template strings :) – ken Apr 01 '15 at 21:06