I need to get the result of lazily evaluated getters into JSON. I'm not interested in preserving the method calls themselves.
I'm working on a project where we have an extensive trees of ES6 objects and have been using the Mustache library to turn these trees into an HTML representation. Throughout the project, when we've needed a simple calculated field, we've used getters.
class Foo {
get bar() {
return 1 + 2;
}
}
Mustache can reference these as if they were properties, and all is good with the world.
Now we're moving to a hosted solution for our templates. However, these object trees are being sent through JSON.stringify
to send the data to the hosted service. In doing so, none of these getters are showing up.
f = new Foo();
JSON.stringify(f); // == '{}', hoping for '{"bar":3}'
If I were to build these objects with the old way of prototypical inheritance using __defineGetter__
it works as I need it to. But that would require me to rebuild all the objects and not use the nice ES6 classes.
f = {};
f.__defineGetter__('bar', function() { return 1 + 2;} );
JSON.stringify(f); // == '{"bar":3}' Woot!
And so I've been trying different methods of rendering these within the class - the ugly brute force way is to rewrite them all as object properties and re-update them as the contents change. Is there a more elegant way?
I was considering adding a toJSON
method to these objects that would generate the appropriate data, but I can't seem to dynamically retrieve a list of getters.
class Foo {
get bar() {
return 1 + 2;
}
toJSON() {
return JSON.stringify(Object.assign({}, this));
}
}
However the Object.assign
ignores the getter as well and doesn't solve the issue. I'd have to resort to getting and storing each value.
toJSON() {
let result = Object.assign({}, this);
result.bar = this.bar;
return JSON.stringify(result);
}
But now I'll have to maintain a separate list of these getters, which will be error prone. (As devs add a getter they'll have to remember to add it to the list or it will mysteriously not show in the template.)
To be clear, I am not interested in serializing the methods, I need the lazily calculated result to show up in the JSON, exactly as it does with the deprecated __defineGetter__
and exactly the way Mustache was handling it.
Any ideas?