Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle date fields from a REST Api in AngularJS?

I've got a REST API that returns JSON data with dates in a standard ISO-8601 format: yyyy-MM-ddTHH:mm:ss:

{
    id: 4
    version: 3
    code: "ADSFASDF"
    definition: "asdflkj"
    type: "CONTAINER"
    value: "1234"
    active: "false"
    formula: false
    validTo: "2014-12-31T05:00:00"
    validFrom: "2010-12-31T10:00:00"
}

My issue is that I'm not quite sure how to deal with this in AngularJS. I have a $resource which GETs, POSTs, etc my API endpoints, but when my data is returned, it is stored in my JS object as as String. I figure that it would be easier to handle as a Date() or a Moment().

In Java, I can use a JsonDeserializer to ensure that all JSON data is properly converted prior to being assigned to the model, but I don't know if there is a similar mechanism in AngularJS.

I've searched around, but can't seem to find anything that implements a generalized solution. I realize that I can use a transformResponse function in my $resource, but that seems like a lot of repeated configuration for every data type that may contain a date.

This leads me to wonder if returning the date in an ISO-8601 format is the best way to proceed? If AngularJS doesn't support it out of the box, I presume that there must be an easier way to deal with dates. How does one deal with dates in AngularJS? Should I just be treating them as text/string objects, and have the API return a pre-formatted version? If so, what is the most flexible format to use in an HTML5 date input box, etc?

like image 302
Eric B. Avatar asked Aug 21 '14 00:08

Eric B.


1 Answers

JSON does not support dates so you will need to send out dates as strings or integers, and convert them to Date objects when suitable. Angular does not do that for you, but you can define a default transformResponse function to $httpProvider. I tried that with $resource and it does affect to it as well, after all, $resource is a higher level abstraction for $http.

If you don't know the structure of your JSON or don't want to rely on it in the conversion function you just need to go it through and convert date-like strings to Date objects.

var convertDates = function(input) {
  for(var key in input) {
    if (!input.hasOwnProperty(key)) continue;

    if (typeof input[key] === "object") {
      convertDates(input[key]);
    } else {
      if (typeof input[key] === "string" && /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$/.test(input[key])) {
        input[key] = new Date(input[key]);
      }
    }
  }
}

app.config(["$httpProvider", function ($httpProvider) {
   $httpProvider.defaults.transformResponse.push(function(responseData){
     convertDates(responseData);
     return responseData;
  });
}]);

Depending on your app this may be unwise from performance perspective (e.g. only a handful of JSON responses contain dates or actually need the dates to be converted) so it might be best to convert the dates in those controllers where that is actually needed.

like image 122
vesse Avatar answered Oct 07 '22 12:10

vesse