emberjs/ember-classic-decorator

errors when extending a service with a constructor

Techn1x opened this issue · 11 comments

This one was a bit tricky to debug, but what I've found is if you extend a service from another service, both native (not-classic), and both use a constructor, (and have ember-classic-decorator package installed), the app will crash

// app/services/abc.js
export default class Abc from Service {
  constructor(...args) {
    super(...args)
  }
}
// app/services/def.js
export default class Def from Abc {
  constructor(...args) {
    super(...args)
  }
  
  someMethod() { ... }
}
// app/routes/application.js
@service def
model() {
  this.def.someMethod() // crashes here
}

You get this fun error

Screenshot from 2021-06-30 23-20-25

The relevant logic that throws that error is here

var ancestorWithInit = findAncestor(this, function(klass) {
return (
klass.prototype.hasOwnProperty('init') || BASE_CLASSES.has(klass)
);
});
if (ancestorWithInit !== null && !BASE_CLASSES.has(ancestorWithInit)) {
throw new Error(

I think the underlying cause is this part of ember.js, which (when debug mode) uses EmberObject with an init hook as an ancestor of the Service instead of the CoreObject.
https://github.com/emberjs/ember.js/blame/297ab0e771409d61dcb014a9a40144cd7fdd5ee8/packages/@ember/-internals/runtime/lib/system/object.js#L34-L51

That's about as far as my understanding goes. It only happens in debug, with ember-classic-decorator installed, so it's not a huge deal, but it's a head-scratcher & time-waster so I wanted to post it in case it's an easy fix or so that others can google their way here and not waste as much time as I did 😅

Workaround, which may not work for some people, is to refactor out the constructor in the higher level ("Def") service

You should not be calling super.constructor(), you should be calling super(). Unsure if that's what's causing the issue.

You should not be calling super.constructor(), you should be calling super(). Unsure if that's what's causing the issue.

Sorry - that was just a mistake in the example, I've edited the post to fix that.

@pzuraq This is now a more annoying problem, and I'm not totally sure what to do about it. It's not a "debug only" problem anymore

I have some native class adapters, that don't use or need the classic decorator. They also don't have any constructor hooks or anything. They extend JSONAPIAdapter. It looks like ember-data's base adapter now extends from EmberObject, so I end up with error messages like this;

Screenshot from 2022-01-18 15-33-20

https://github.com/emberjs/data/blob/0a8e0a4d1c2f99b707dc565eb555c446f099d4fa/packages/adapter/addon/index.ts#L205

It seems that removing the name from a class works for some reason that I don't understand, which is a little concerning..

errors

// some-adapter.js
import JSONAPIAdapter from '@ember-data/adapter/json-api'

export default class SomeAdapter extends JSONAPIAdapter {}

works

// some-adapter.js
import JSONAPIAdapter from '@ember-data/adapter/json-api'

export default class extends JSONAPIAdapter {}

This library is meant to be transitional, you should work to remove it from your codebase and convert asap. I'm not longer maintaining it as I don't have the time and most people have already worked through the transition.

No worries. I realise I'm a little behind in some transitional work in my codebases (though, we are on Ember 3.28 LTS, and I was under the impression that this addon would attempt to facilitate classic classes up until 4.0)

I'm not sure what the implications are of using native classes for adapters and serializers that extend from from ember-data's that are now based on EmberObject. Hopefully nothing major and I can safely ignore these errors.... (though It's unfortunate that I cannot actually turn them off)

I'll apply my above workaround of removing the class name, which I am guessing is a bug that allows a class to skip ember-classic-decorator's checks, and sit tight to see if anyone else hits this issue.

I appreciate your time in reading my comments!

Another workaround we have found is to pin ember-classic-decorator to 2.0.0 as a yarn resolution. 2.0.1 seems to bring the problems back. This is a suitable workable solution for now 👍

Still an issue on ember-classic-decorator v3.0.1 - was hoping the updates would fix it.

Remaining locked to v2 for now