Fixing EmberObject.create no longer supports defining computed properties


#1

I followed EmberMaps guide and updated the Ember app from 3.5.1 to 3.7.1 and one route fails with the following message:

Assertion Failed: EmberObject.create no longer supports defining computed properties. Define computed properties using extend() or reopen() before calling create().

I’ve already searched for possible appearance of EmberObject.create in the code and fixed some ones as follows:

#components/event-form.js

import Component from '@ember/component';
import { inject as service } from '@ember/service';
import { computed } from '@ember/object';
import { translationMacro as t } from "ember-i18n";
import EmberObject from '@ember/object';

export default Component.extend({
...

_allSportsEntry() {
    let all = EmberObject.extend({
      id: 999999,
      label: 'All sports'
    }).create();

    return all;
  }
});

There are no other search results, only in some add-ons:

  • dist/assets/vendor.js
  • node_modules/ember-data-url-tempplates/addon/mixins/url-template.js
  • node_modules/ember-i18n/addon/helper.js and some testing modules that I think should not be taken into account.

How to find where it comes from and to fix that ? Here is the screenshot of the browser console displaying the error. When switching back to 3.5.1 version, everything works as needed.

Here is the route I hit when it happens (the same error in edit route as well):

#routes/country-events/new.js

export default Route.extend(AuthenticatedRouteMixin, {
  currentShop: service(),

  model() {
    return RSVP.hash({
      countries: this.store.findAll('country', { include: 'languages' }),
      sports:    this.store.findAll('sport'),
      event:     this.store.createRecord('event')
    });
  }
});

Any ideas ? Thank you !


#2

The error has a “stack” property which shows the call stack when the error occurred. Those can be hard to dig into but if you build the app and then look in the dist location (dist/assets/vendor.js or dist/assets/<appname>.js by default) and then go to the line number indicated in the stack trace you can usually diagnose what addon it’s coming from. If you found those two addons “ember-data-url-tempplates” and “ember-i18n” you can also make sure you’re on the newest versions and look in the “issues” section of the github to see if anyone has reported them.


#3

@dknutsen Thank you very much for the response. Observing the indicated line number in the cosole stack trace, - it is coming from vendor.js, line 65823, corresponding to the following code in class LowLevelVM, function evaluateInner when calling evaluateSyscall method:

class LowLevelVM {
...
evaluateInner(opcode, vm) {
            if (opcode.isMachine) {
                this.evaluateMachine(opcode);
            } else {
                this.evaluateSyscall(opcode, vm);
            }
        }

Unfortunately, i didn’t find any traces indicating teh add-on the error comes from.


#4

It seems like the problem comes from setting the data used by ember-power-select drop-downs. Once I comment them out in the component template, the error disappears. Here is how I load data in the routes/country-events/new.js:

export default Route.extend(AuthenticatedRouteMixin, {
  currentShop: service(),

  model() {
    return RSVP.hash({
      countries: this.store.findAll('country', { include: 'languages' }),
      sports:    this.store.findAll('sport'),
      event:     this.store.createRecord('event')
    });
  }
});

Then, calling the component from the templates/country-events/new.hbs:

{{#event-form
  event=model.event
  sports=model.sports
  countries=model.countries
  submitAction=(action "save")
}}
  <button
    type="submit"
    class="btn btn-success"
    disabled={{v-get model.event "isInvalid"}}
  >
    {{t "buttons.save"}}
  </button>
{{/event-form}}

I init the ember-power selects in the components/event-form.js as follows:

export default Component.extend({
  tagName:     '',
  currentShop: service(),
  i18n:        service(),
  allSportsEntry: null,
  sports: [],
  allSports: [],

init() {
    this._super(...arguments);
    this.set('sportPlaceholder', t('components.event-form.sport.placeholder'));
    this.set('aCountry', this.get('currentShop.shop.country'));
    this.set('aLanguage', this.get('currentShop.shop.country.languages.firstObject'));
    console.log('aCountry: ' + this.get('aCountry.name'));
    console.log('aLanguage: ' + this.get('aLanguage.tag'));
    this.set('allSportsEntry', this._allSportsEntry());
    this._setSports();
    this._setSelectedSports();
  },
...

And what is weird - when displaying aLanguage in the consoles - it is undefined:frowning:. Why so ?

Here is the template component code regarding ember-power selects in templates/ components/event-form.hbs:

...
{{#power-select
            class="form-control"
            selected=aCountry
            options=countries
            searchField="name"
            onchange=(action "chooseCountry")
          as |country|
          }}
            {{country.name}}
          {{/power-select}}
...

{{#power-select
            class="form-control"
            selected=aLanguage
            options=aCountry.languages
            searchField="tag"
            onchange=(action (mut aLanguage))
          as |language|
          }}
            {{language.tag}}
          {{/power-select}}
....

#5

Yay, the first step is done, - I partially fixed the error for 2 ember-power selects just by declaring 2 missing variables (aLanguage, aCountry in component JS file (components/event-form.js) and setting them them to null:

export default Component.extend({
...
  aLanguage: null,
  aCountry: null,

init() {
    this._super(...arguments);
    this.set('sportPlaceholder', t('components.event-form.sport.placeholder'));
    this.set('aCountry', this.get('currentShop.shop.country'));
    this.set('aLanguage', this.get('currentShop.shop.country.languages.firstObject'));
   this.set('allSportsEntry', this._allSportsEntry());
    this._setSports();
    this._setSelectedSports();
  },
...

After uncommenting the drop-down for country and languages, there is no mo error. Next step is to fix the multiple select displaying sports, - it still raises the error about EmberObject.create() call event after modifying it as follows in the same component:

_allSportsEntry() {
    let all = EmberObject.extend({
      id: 999999,
      label: 'All sports'
    }).create();

    return all;
  }

#6

Ouff ! Fixed it. Another variable was missing in the component SJ file - placeholder text used by ember-power-seelct for sports:

export default Component.extend({
..
sportPlaceholder: t('components.event-form.sport.placeholder'),

To fix a EmberObject.create() call error, I declared a new variable by extending EmberObject as follows:

let AllSportsEntry = EmberObject.extend({
  id: 999999,
  label: 'All sports'
});

export default Component.extend({
...
allSportsEntryLabel: t('components.event-form.sports.all'),
...
_createAllSportsEntry() {
    let all = AllSportsEntry.create({
      label: this.get('allSportsEntryLabel')
    });

    return all;
  }

And there is no more errors, everything works as before, with 3.5.2 version, yay !


#7

Awesome! Glad you got it to work. Sometimes those issues can be really hard to track down.