Transforming posted Data in Angular

Home / Transforming posted Data in Angular

Recently, I was reading an article about modifying data on a response in Angular. With my previous posts dealing with TimeZones and such, it made me curious if I could also transform my data on each POST in Angular.


For example, I have many JavaScript objects with startDate and endDate properties. These dates, in JavaScript/Angualr will wind up being UTC dates. For my purposes, this isn’t very useful. I really need those dates to always be the local datetime of the user. Why you might ask? These dates are compared to other dates that are that of a specified “kind.” IE – not UTC. Philosophically, and yes I’m going on a tangent, UTC is great for keeping things all relative on the same time scale. But, when we’re looking at when something happens relative to other dates that are non-UTC/non-TimeZone specific, all we really care about is the user’s datetime in the moment.

At any rate, Angular provides nice mechanisms for manipulating/transforming data returned on response and data posted on requests. In my case, what I really wanted to do is globally change any property called startDate or endDate to a local date time. ASP.NET MVC parses JavaScript’s output from “toLocaleString” as a DateTime just fine, so this seemed like a good candidate in the transforming of my data.

To add a transform for all requests, we access the $httpProvider service and its “transformRequest” default collection of transform functions. We want to inject our own transform without affecting other transforms. The Angular docs provided a nice “appendTransform” example, so I used that as my basis. The code below adds my “transformDates” method to the transform request collection.

var appendTransform = function appendTransform(defaults, transform) {

   // We can't guarantee that the default transformation is an array
   defaults = angular.isArray(defaults) ? defaults : [defaults];

   // Append the new transformation to the defaults
   return defaults.concat(transform);
};

var transformDates = function (data) {
   var obj = angular.fromJson(data);
   for (var key in obj) {
	   if (!obj.hasOwnProperty(key)) continue;
	   if (key === 'startDate' || key === 'endDate')
	   {
		   var value = new Date(obj[key]);
		   obj[key] = value.toLocaleString();  
	   }
   }

   return angular.toJson(obj);
};

$httpProvider.defaults.transformRequest = appendTransform($httpProvider.defaults.transformRequest, function (data) {
   return transformDates(data);
});

Basically, on every POST/PUT, the “transformDates” methods will receive the request data from Angular. It comes in as a JSON string. The method deserializes this, and then iterates over the object’s keys to find the (2) properties I’m interested in transforming. The values are converted to a Date and then to a Local date string. Finally, the transform serializes the object back to JSON and returns it to be sent on HTTP request.

All in all, this is a nice mechanism to deal with global transformations of data without cluttering up controllers and services.

Leave a Reply