Skip to main content

Blog

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);
});

ASP.NET MVC and WebAPI – “The parameters dictionary contains a null entry for parameter”

WWW Logo

When working in ASP.NET MVC and WebAPI you may run across this exception.  Consider the following controller action:

[HttpPost]
[Route("api/SomeController/SomeAction")]
public void SomeAction(int id)
{
.....
}

And a simple AngularJS ajax call to the method:

var someAction= function (id) {
var d = $q.defer();
$http.post('api/SomeController/SomeAction', id)
.success(function (data) {
d.resolve(data);
})
.error(function (data) {
d.reject(data);
});
return d.promise;
};

The ajax call can be from any client-side framework, AngularJS, jQuery, etc.  What’s important is the routing to the MVC controller action and, more specifically, how WebAPI performs the parameter binding.

By default, for value types (int, bool, string, etc) WebAPI will try and get a parameter value for a simple type from the URL.  This obviously creates an issue in this case since we are using a POST request; the parameter value will be in the body of the HTTP request and not in the URL.

In order to resolve this issue the parameter in the controller action must be decorated with the [FromBody] attribute indicating that WebAPI should look in the HTTP request body when performing the parameter binding.
The controller action would then look like this:

[HttpPost]
[Route("api/SomeController/SomeAction")]
public void SomeAction([FromBody] int id)
{
.....
}

Now the parameter binding works and the parameter value is sent to the action method just fine.

Mike Wasson has an excellent article with a lot more details here:

http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api

IIS – “The page cannot be displayed because an internal server error has occurred.”

WWW Logo

I recently ran across this common error when migrating an IIS7.5 web site to IIS8.5.

Default500Error

This error occurred regardless of what I was trying to access; the server responded with it for all requests. For this particular site I had exported the site and app pool configuration from the old server and imported it into the new server using appcmd.  Everything seemed to be fine with the application cofigurations.

It didn’t matter if it was static content or a request to an application.  Also, I had detailed error messages enabled to see what the problem was but nothing I tried returned a detailed error, only this generic error.  It seems to me now that a site level configuration error will prohibit detailed error messages from being returned to the client.  I got lucky when trying to look at different configuration elements from within IIS manager.  I got lucky when clicking on one of the configuration items.  I happened to try and open the MIME Types element on the site level and received an error message stating that there was a duplicate MIME type for MP4 files:

DupeMIMEType

IIS7.5 does not include a mapping for MP4 out of the box so on the old server I had to add it manually:

IIS7_5_MIME

IIS8.5 now includes this type, which is a good thing since it’s obviously a popular format.  I opened the web.config file of the site on the IIS8.5 server and saw the mapping:

IIS8_5_MIME

I then removed the entire <staticContent> section that is highlighted and the site started behaving properly.  My site has a fairly simple configuration so if you have more than just the one MIME type in your <staticContent> section then you obviously don’t want to remove the whole section, but rather just the duplicate mapping.

Songs and Videos from Camp Lael Summer 2014 Jr. High Session

Camp Lael Diamond Logo

Here are the songs and videos that I used during the Jr. High session at Camp Lael this summer.  The song list contains the songs we sang together (before my voice started going…) including the CCLI number so that worship leaders can look them up in Song Select.  The videos are all the other videos we watched during my camp pastor sessions.

Read More