The AngularJS $http service is great for most any communication you need to do with the web services that are likely backing your single-page-application. However one place where it doesn’t quite do what you usually want is in the deserialization of dates.

Using $http to post a blog entry for example is pretty easy:

myPost = 
  id: 123
  title: 'Using HTTP Interceptors to Deserialize Dates'
  status: 'draft'
  creationDate: new Date()
  body: 'TBD'
$'/api/blog', myPost)

This results in the following JSON being posted to the server:

  "id": 123
  "title": "Using HTTP Interceptors to Deserialize Dates",
  "status": "draft",
  "creationDate": "2014-08-13T10:13:39.399Z",
  "body": "TBD"

This is great. Notice that the service has automatically serialized the creation date to an ISO-8601 compliant string. I couldn’t ask for more… or could I?

What if I want to now get that post back:

$http.get("/api/blog/123").success (blog) ->
    console.log blog.creationDate    
    console.log typeof blog.creationDate

Assuming that the endpoint returns the exact same JSON that was just posted, this code will output:


This is not the end of the world but it may not be what one is expecting. The expectation is usually that if I put a Date instance into a serialization function, then I get a Date instance out of the matching deserialization function.

Fortunately, this situation is easily remedied with a Angular http interceptor. Angular’s $httpProvider service allows one to configure interceptors that can pre-process all out-going requests before they are sent and post-process all received responses before handing them back to the calling application. A response post-processor to find all ISO-8601 date strings and convert them to actual Date objects is easy to implement.

angular.module('myModule', []).config([
  ($httpProvider) ->
    $httpProvider.interceptors.push [
        #Matches YYYY-MM-ddThh:mm:ss.sssZ where .sss is optional
        iso8601RegEx = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?Z$/
        response: (response) ->
          convertDates = (obj) ->
            for key, value of obj
              #If it is a string of the expected form convert to date  
              type = typeof value
              if type is 'string' and iso8601RegEx.test value
                  obj[key] = new Date(value)
              #Recursively evaluate nested objects
              else if type is 'object'
                convertDates value

And there you have it. Happy coding!