1

I am successfully calling $http.get in my Angular controller and getting back a large json object. Like this:

var self=this;
self.createNewStatusReport = function()
{
    $http.get(self.NewStatusReportUrl).then(function(response)
    {
        self.AngularModel.StatusReportJsons.push(response.data);
    });
};

The returned json includes many dates. The format, unfortunately, looks like this: /Date(1420099200000)/. Here's a simplified piece of the response data:

{
    "StatusReportID": 25, 
    "DueDate": "/Date(1468566000000)/", 
    "SubmitDate": null,
    "WorkStatement": [
    {
        "WorkStatementID": 41, 
        "Milestone": [
        {
            "MilestoneID": 501,
            "ContractorComments": null, 
            "Title": "Do some specific piece of work", 
            "StartDate": "/Date(1459494000000)/", 
            "EndDate": "/Date(1469948400000)/", 
            "IsCompleted": false, 
            ...

I also have (some) control over the server side, but can't change the date types in StatusReportJson from DateTime? to string. It is MVC written in C#:

[HttpGet]
public JsonResult NewStatusReport(string agreementNumber)
{
    var statusReport = StatusReports.GetStatusReport(25);
    return Json(new StatusReportJson(statusReport), JsonRequestBehavior.AllowGet);
}

Is there an easy way to recursively convert these date strings to date objects? The response data comes to me already parsed; can I insert my own parse step? On the server side, can I make the dates come in as date strings that look more like "2016-04-01T00:00:00" or simply "2016-04-01" without modifying my StatusReportJson object's data types? Others have already solved the conversion problem here: How do I format a Microsoft JSON date? I need help structuring where to put the solution so it is effective in my case. Thanks for helping!

8
  • Simple to loop over data and convert each instance before pushing to array. Having to do client side data transformations is not uncommon Commented Jul 2, 2016 at 17:25
  • That creates a dependency I would rather not have. If the StatusReportJson changes on the server side, which it is likely to do, I don't want to have to change the client side to match. Makes for less maintainable code. Commented Jul 2, 2016 at 17:36
  • I have no idea how you can change things at server-side. But at client-side, you could just use a filter that transforms the /Date()/ string into a number, and then passes that number to the standard date filter. Commented Jul 2, 2016 at 17:36
  • "Makes for less maintainable code" ... doesn't make sense. Commented Jul 2, 2016 at 17:39
  • Interesting idea. Are you talking about an Angular filter? (I'm not very familiar with them yet.) Assuming I could look up how to write one, how would I put it in place to work here, before the json is parsed? Commented Jul 2, 2016 at 17:40

3 Answers 3

1

Hope this solves your problem:

$scope.DateIssue = function(input) {
input = '/Date(1468566000000)/';
$scope.formatedDate = input.toString().replace('/Date(', '').replace(')/', '');
$scope.formatedDate = $filter('date', $scope.formatedDate);
return $scope.formatedDate

};

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for this. Hmmm. But I have an object, not a string. Is there a way to run a function which pre-processes the response before angular does its json deserialization?
you can convert that object as string and use this function.
0

Here's how I solved this. First, I used the JavaScript serializer on the server side like this:

[HttpGet]
public JsonResult NewStatusReport(string agreementNumber)
{
    var statusReport = StatusReports.GetStatusReport(25);
    var statusReportJson = new StatusReportJson(statusReport);
    var json = new JavaScriptSerializer().Serialize(statusReportJson);
    return Json(json, JsonRequestBehavior.AllowGet);
}

Then, on the client side, I pulled in code from this excellent page http://erraticdev.blogspot.com/2010/12/converting-dates-in-json-strings-using.html and called it like this:

var self = this;
$http.get(self.NewStatusReportUrl).then(function(response)
{
    var jsonObject = jQuery.parseJSON(response.data, true);
    self.AngularModel.StatusReportJsons.push(jsonObject);
});

Thanks to Robert Koritnik for the answer! And thanks to everyone who helped!

Comments

0

A little late, but I thought helpful. Most of the suggestions were to locally convert it. In my case the date is returned as string (with Timezone info).

E.g. '2018-06-01T13:57:41.3867449Z'

So I created a common service for getJson & PostJson and in handled responses there with '$q'.

if (response.data) {
    // Check for datetime object & convert  
    // TODO:: *** May impact performance, so check later or use momentJS
    //console.info('Before-convertDateStringsToDates:', new Date());
    appUtils.convertDateStringsToDates(response.data);
    //console.info('After-convertDateStringsToDates:', new Date());
}

My appUtil method is as below:

// --------------------------------------------------------------------------------
// Ref: http://aboutcode.net/2013/07/27/json-date-parsing-angularjs.html
// Function to convert string (as ReGex format) property to date - used as generic in Common Serivce.
convertDateStringsToDates(input) {
    // ReGex for format we receive from Web API e.g. "1980-05-09T00:00:00Z"
    var jsonDateTimeFormatRegex = "((?:2|1)\\d{3}(?:-|\\/)(?:(?:0[1-9])|(?:1[0-2]))(?:-|\\/)(?:(?:0[1-9])|(?:[1-2][0-9])|(?:3[0-1]))(?:T|\\s)(?:(?:[0-1][0-9])|(?:2[0-3])):(?:[0-5][0-9]):(?:[0-5][0-9]))";
    // Ignore things that aren't objects.
    if (typeof input !== "object") return input;

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

        var value = input[key];
        var match;
        // Check for string properties which look like dates.
        // TODO: Improve this regex to better match ISO 8601 date strings.
        if (typeof value === "string" && (match = value.match(jsonDateTimeFormatRegex))) {
            // Assume that Date.parse can parse ISO 8601 strings, or has been shimmed in older browsers to do so.
            //console.info(match[0]);
            var date = new Date(match[0]); // Need to convert to UTC. Ref: https://stackoverflow.com/a/14006555/1161069
            input[key] = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds()));

            // var milliseconds = Date.parse(match[0]);
            // if (!isNaN(milliseconds)) {
            //     input[key] = new Date(milliseconds);
            // }
        } else if (typeof value === "object") {
            // Recurse into object
            this.convertDateStringsToDates(value);
        }
    }
}

Now, after each GET or POST request, I get my JSON with proper dates.

Just in case someone wants to know Web API code, it's as below:

public static void Register(HttpConfiguration config)
{
    // Web API configuration and services

    //var cors = new System.Web.Http.Cors.EnableCorsAttribute("*", "*", "*");
    config.EnableCors(cors);

    // Web API routes
    config.MapHttpAttributeRoutes();

    // other code ......

    var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().First();
    //jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();

    JsonSerializerSettings jSettings = new JsonSerializerSettings()
    {
        Formatting = Formatting.None
    };
    jSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
    jsonFormatter.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Local;
    jsonFormatter.SerializerSettings = jSettings;

    // rest of the code....
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.