Hi,
Me and my collegues have met interesting case:
class Parent {
constructor() {
this.innerCollection = [];
}
@computed get collection() {
return this.innerCollection;
}
}
class Child extends Parent {
@computed get collection() {
return super.collection;
}
}
let child = new Child()
let length = child.collection.length
It fails with:
mobx.js?6a62:2432 Uncaught Error: [mobx] Invariant failed: Cycle detected in computation [email protected] in 'function get() {
return (0, get3.default)((0, getPrototypeOf2.default)(Child.prototype), 'collection', this);
}'
Is this possible to fix, or any workaround?
@computed is applied twice. Same error can be reproduced like this:
class T {
@computed
@computed
get prop() {
return 1;
}
}
console.log(new T().prop)
Properties live on the instance (computed or not), so there is no 'super' version of them in javascript (or any other language that I know of), unlike functions that live on the prototype. Similar to how you cannot do this.name = 3; console.log(this.name, super.name). That will always print 3 twice, regardless what value you gave it in the super constructor.
The work around here is to do to something like:
class Parent {
@computed get collection() {
return this.getCollectionImpl();
}
getCollectionImpl() {
return this._collection
}
}
class Child {
getCollectionImpl() {
return super.getCollectionImpl().concat([1,2,3])
}
}
@mweststrate
Probably I missunderstood something but
@computed get collection()
is not property but getter function which has access to super. At least if we remove @computed it works as expected.
@satispunk yep because by default getters are declared on the prototype. However computed getters have local state (e.g. the memoization), so we would need to do really weird tricks to allow it to be defined 'twice' on the same instance.
You can best compare it with doing
function a() { super.a() } versus a = () => super.a().
Closing the issue, I don't think there is much value in working around this. Will add a note to the docs.