Skip to main content

Serialize Javascript Object with getter Property

JavaScript Logo

In one of my current Aurelia projects I’m using a data object that contains a calculated field. The calculated field is a simple sum of two other fields on the object. Here is an example class definition that illustrates it:

export class SomeItem {
x;
y;

constructor(x, y) {
this.x = x;
this.y = y;
}

get z() {
return this.x + this.y;
}
}

I use this class in two-way binding on an Aurelia custom component. The x and y fields are two-way bound to contenteditable DIV elements in the component. The calculated z field is one-way (display-only) bound to another DIV in the component. The class itself works just fine, the calculated field displays, etc. However, when serializing the object to JSON and sending the data to an API the calculated field is missing from the serialized JSON data.

I’m using the Aurelia fetch client to call my API and the included json helper for serialization. The json helper just stringifies the object and then packs it into a blob:


return new Blob([JSON.stringify(body)], { type: 'application/json' });

The problem with my getter approach is that functions in Javascript are not enumerable by default, which means any kind of serialization automation is not going to see the property on the object by default when it is iterating through the object’s property list. JSON serialization picked up the x and y properties on my class just fine, but not the z property.

To fix this I had to manually define the property on the object and set it to be enumerable. So now the class looks like this:

export class SomeItem {
x;
y;

constructor(x, y) {
this.x = x;
this.y = y;
}

Object.defineProperty(this, 'z', {
enumerable: true, //this adds the function property to the list of property keys
get: function() {
return this.x + this.y;
}
}
}

After setting the property function to be enumerable the JSON serializer picked it right up and it’s now flowing through to my API as desired.

AngularJS – “Error: 10 $digest() iterations reached. Aborting!” with Array Extension Method

Angular Logo

Using AngularJS 1.4.1. I had this markup with multiple calls to a custom directive:

<div ng-controller="SomeController">
<myDirective data="myData.Where('IsOpen',true)"></myDirective>
<myDirective data="myData.Where('IsOpen',false)"></myDirective>
</div>

myData is an array and Where() is an extension method that iterates over the array returning a new array containing any items from the original where the IsOpen property matches the bool value in the second parameter.

In the controller I set $scope.data like this:

DataService.getData().then(function(results){
$scope.data = results;
});

Calling the Where() extension method from the directive like in the above markup was the problem. To fix this issue I moved the call to the extension method into the controller instead of the markup:

<div ng-controller="SomeController">
<myDirective data="openData"></myDirective>
<myDirective data="closedData"></myDirective>
</div>

and the new controller code:

DataService.getData().then(function(results){
$scope.openData = results.Where('IsOpen',true);
$scope.closedData = results.Where('IsOpen',false);
});