Follow up of
https://github.com/ember-decorators/ember-decorators/issues/115#issuecomment-427057102
and new issue here, as requested by @rwjblue
Extending a native class with .extend which itself is extending EmberObject is throwing a
TypeError: Class constructor CLASS_NAME cannot be invoked without 'new'
The motivation of this is being able to use native classes and mixins, like this:
class Foo extends EmberObject {
// ...
}
const Bar = Foo.extend({
// ...
});
class Baz extends Bar {
// ...
}
See this ember-twiddle:
https://canary.ember-twiddle.com/b365ecfbc29444455d082cf1b295156b?openFiles=tests.foo-test.js%2C
Is this the same as https://discuss.emberjs.com/t/ember-3-2-ember-decorators-subclassing-bug/15380? We also hit that issue.
Yes, it is the same issue.
@rwjblue - is there any timeframe on fixing this? Do you have any idea where the problem might be? Because we've been hitting this a lot when using native classes in TypeScript (and using the language with .extend sucks a lot) and I wonder whether to postpone migrating to TypeScript more of our code.
If you create a patched version extend in your app so that babel compiles it according to your App settings.
import EmberObject from "@ember/object";
EmberObject.extend = function (...args) {
class Class extends this;
Class.reopen(...args);
return Class;
}
export default EmberObject;
then import from that in your app it should workaround the problem until we publish the es so that ember-cli compiles ember with the same babel settings.
@krisselden - thank you for the suggested workaround! For any future readers, the class Class extends this; line should actually say class Class extends this {} instead. :)
This is fixed in the current release, so I'm going to go ahead and close...
@rwjblue - this is still not fixed for me on 3.6.1. Getting the same error as in the first post of this issue. I think this should be reopened. Or am I missing something?
Happy to reopen with a demo repo
Just in case anybody is wondering about the ember-twiddle tests which I had posted in the OP, those are wrong... I had incorrectly mixed the properties on the class prototype (.extend) and class instance (native class properties). 3.6.1 is working fine, though.
@rwjblue - here is a reproduction. It took me a while but it was quite simple in the end - it's because of the targets.js file.
@rwjblue - ping. :) Did you manage to take a look at the reproduction? Let's reopen the issue so we don't forget it. :)
Yes, I did but I鈥檓 not sure we can/should reopen. Sorry, I鈥檓 out with the family at the moment but will try to explain once I鈥檓 back at a keyboard...
@rwjblue - I don't want to be annoying, but could you please explain why you don't think this is a bug? :) Thanks!
@rwjblue - after updating @babel packages from 7.3.4 to 7.4.0 this started happening again. Nothing else has changed in my project. Should I try to create a reproduction or is this a known problem?
Also, if you could explain why adding edge to targets.js causes the same problem and why you consider this to not be a bug?
I've pushed a commit in my reproduction repo that showcases the latest problem. Both issues can be seen in it - edge in targets.js causing TypeError: Class constructor Model cannot be invoked without 'new' and updating @babel packages to 7.4.0 causing the same error. Should I open a new issue for this?
I have the same issue after upgrade of dependencies in my repo. Upgrade of direct dependencies was OK but after removing yarn.lock and generating new one - minor upgrades took place in indirect dependencies (i.e. dependencies of dependencies). E.g.
@babel/preset-env was upgraded from 7.3.1 to 7.4.3 (I don't if this is a reason - this is my guess). I use also TS and ember-cli-typescript in the newest version
Error which I have:
Error while processing route: index Class constructor XXX cannot be invoked without 'new' TypeError: Class constructor XXX cannot be invoked without 'new'. It seems that problem is with generated code for CoreObject. See details below
Details with generated code AFTER upgrade
Part of the stack trace (from generated code):
CoreObject.extend = function extend() {
var Class =
/*#__PURE__*/
function (_this) {
(0, _emberBabel.inheritsLoose)(Class, _this);
function Class() {
// !!!!!!!!!!!!!!!!!!!!!!
return _this.apply(this, arguments) || this; // THIS LINE EXPLODED
// !!!!!!!!!!!!!!!!!!!!!!
}
return Class;
}(this);
_reopen.apply(Class.PrototypeMixin, arguments);
return Class;
}
and generated Class definiton which extends XXX class (_base below). These definitions below are the same BEFORE and AFTER upgrade
Object.defineProperty(_exports, "__esModule", {
value: true
});
_exports.ClassWhichExtendsXXX = void 0;
class ClassWhichExtendsXXX extends _base.default.extend({
// some computed properties
}) {}
_exports.ClassWhichExtendsXXX = ClassWhichExtendsXXX;
generated XXX class (_base above):
Object.defineProperty(_exports, "__esModule", {
value: true
});
_exports.default = void 0;
class XXX extends Ember.Service.extend({
init() {
this._super(...arguments);
},
// ...
}) {}
_exports.default = XXX;
In the code we crate new instance of ClassWhichExtendsXXX with new (new ClassWhichExtendsXXX()) keywords (I tried also .create() from ember object: ClassWhichExtendsXXX.create()`.
Details with generated code BEFORE upgrade
Only difference is in vendor (CoreObject):
static extend() {
let Class = class extends this {};
reopen.apply(Class.PrototypeMixin, arguments);
return Class;
}
@Krzyrok - I opened another issue for that. They fixed it, we're waiting for the new version to fix it. :)
Great! Thanks for link :)