I see the previous question regarding this: Lazy computed properties in Immutable.js Records? but the accepted answer does not work with ImmutableJS 4+ (as documented because the factory function instead of class constructor mechanism, but I also tested it out after seeing it here, creating a new record with .set() will leave the lazy property behind.).
I arrived at the following solution, which seems to work in my rudimentary testing, but I am not sure of all the ramifications with regards to JS classes, and manually adding a property like this.
Is this a foot gun in some way? also how to make Typescript to accept the if(this.precomputed === undefined) part without adding precomputed to the record props (which it must not be added to).
class ABRecord extends Immutable.Record({
a: 1,
b: 2,}){
getPrecomputed(){
if(this.precomputed === undefined){
console.log("Ran computation");
var value = `${this.a} ${this.b}`;
Object.defineProperty(this, 'precomputed', {
value: value
});
}
return this.precomputed;
}
}
const a1 = new ABRecord();
console.log(a1.toJS()); // {a:1,b:2}
console.log(a1.getPrecomputed()); // "Ran computation" \n "1 2"
console.log(a1.getPrecomputed()); // "1 2"
const a2 = a1.set("a", 2);
console.log(a2.toJS()); // {a:2,b:2}
console.log(a2.getPrecomputed()); // "Ran computation" \n "2 2"
console.log(a2.getPrecomputed()); // "2 2"
const a1_but_different = new ABRecord({a:1,b:2});
console.log(a1 === a1_but_different); // false // to ensure its really a diff object
console.log(a1.equals(a1_but_different)); // true // to ensure that structural equality still works regardless if precomputed is present yet or not.
<script src="https://cdnjs.cloudflare.com/ajax/libs/immutable/4.3.2/immutable.min.js"></script>