Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JSON stringify ES6 class property with getter/setter

I have a JavaScript ES6 class that has a property set with set and accessed with get functions. It is also a constructor parameter so the class can be instantiated with said property.

class MyClass {   constructor(property) {     this.property = property   }    set property(prop) {   // Some validation etc.   this._property = prop   }    get property() {     return this._property   } } 

I use _property to escape the JS gotcha of using get/set that results in an infinite loop if I set directly to property.

Now I need to stringify an instance of MyClass to send it with a HTTP request. The stringified JSON is an object like:

{    //...    _property: } 

I need the resulting JSON string to preserve property so the service I am sending it to can parse it correctly. I also need property to remain in the constructor because I need to construct instances of MyClass from JSON sent by the service (which is sending objects with property not _property).

How do I get around this? Should I just intercept the MyClass instance before sending it to the HTTP request and mutate _property to property using regex? This seems ugly, but I will be able to keep my current code.

Alternatively I can intercept the JSON being sent to the client from the service and instantiate MyClass with a totally different property name. However this means a different representation of the class either side of the service.

like image 846
Thomas Chia Avatar asked Feb 08 '17 07:02

Thomas Chia


2 Answers

You can use toJSON method to customise the way your class serialises to JSON:

class MyClass {   constructor(property) {     this.property = property   }    set property(prop) {   // Some validation etc.   this._property = prop   }    get property() {     return this._property   }    toJSON() {     return {       property: this.property     }   } } 
like image 172
Amadan Avatar answered Sep 29 '22 04:09

Amadan


If you want to avoid calling toJson, there is another solution using enumerable and writable:

class MyClass {    constructor(property) {      Object.defineProperties(this, {         _property: {writable: true, enumerable: false},         property: {             get: function () { return this._property; },             set: function (property) { this._property = property; },             enumerable: true         }     });      this.property = property;   }  } 
like image 39
Richard Časár Avatar answered Sep 29 '22 05:09

Richard Časár