Skip to content

Record(...) subclasses don't produce fully initialized instances #1495

Closed
@gbenson-wikia

Description

@gbenson-wikia

What happened

This is easier to explain with the code part first...

How to reproduce

Ensure you've got babel-plugin-transform-class-properties as part of your babel config

class Example extends Record( { foo: '' } ) {
  mySetterFunction = value => this.set('foo', value);
}

const temp = new Example();
temp  // an instance of Example
temp.mySetterFunction    // a function
temp.mySetterFunction('bar')    // also an instance of Example
temp.mySetterFunction('bar').mySetterFunction    // undefined - expected this to be a function

What's going on?

While it's normally pretty strange to want anything to happen in the constructor of a Record subclass, Babel will transform public instance fields declarations to happen inside the constructor of the Example class. That constructor gets called as expected when new Example() is called, which is why the bound function appears as a public instance field at the beginning. However, since .set() gets its "new" instance from the Record factory - which doesn't run the constructor - the Example Record appears to "lose" its functions every time that .set() gets called.

Ideally, the class constructor would be called a single time when new Example() is called, so that the instance of the Record that gets stamped out by the factory will have the appropriate instance fields set. Second best would be to have the Record factory call the constructor when stamping out a new instance.

In the meantime, there are two workarounds for this:

  1. whenever you call .set(), be sure to wrap the result in new Example(...), so that the constructor gets called (and therefore the public instance fields show up properly)

  2. don't use public instance fields, so that the functions become part of the class prototype instead of values on the instance itself

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions