Does ko.toJSON() work with dates?
Asked Answered
G

2

6

I am using knockoutjs on an asp.net mvc page. I am using ajax to persist a form back to the server by calling ko.toJSON(viewModel) and then posting the results back to the server using jQuery. All of the properties on the view model are successfully serialized except for the Javascript date which is persisted as an empty object.

Declaration:

var viewModel = {
    startTime: ko.observable(),
    type: ko.observable(),
    durationInMinutes: ko.observable(),
    notes: ko.observable()
};

Save Data:

var postData = ko.toJSON(viewModel); 
$.ajax({
    url: "/data",
    type: "POST",
    data: postData,
    dataType: "json",
    contentType: "application/json; charset=utf-8",
    success: function () {
        console.log('success!');
    },
    error: function () {
        console.log('fail!');
    }
});

The console.log value of viewModel.startTime() is:

Date {Tue May 10 2011 11:30:00 GMT-0500 (Central Daylight Time)}

After line 1 of Save Data, the value of postData is:

{
    "startTime": {},
    "type": "1",
    "durationInMinutes": "45",
    "notes": "asfasdfasdfasdfasdfasdfasdfas",
    "displayableStartTime": "10-May 11:30"
}

If I expand line 1 of Save Data to

var jsonEvent = ko.toJS(viewModel);
jsonEvent.startTime = viewModel.startTime();
var postData = JSON.stringify(jsonEvent);

The value of postData is:

{
    "startTime": "2011-05-10T16:30:00.000Z",
    "type": "1",
    "durationInMinutes": "45",
    "notes": "asfasdfasdfasdfasdfasdfasdfas",
    "displayableStartTime": "10-May 11:30"
}

Can anyone explain what might be going on and how I might be able to get knockoutjs to handle the date object?

Gander answered 9/5, 2011 at 21:38 Comment(3)
There is an issue logged for this one here: github.com/SteveSanderson/knockout/issues/55. Are you okay with the format in your last example?Katricekatrina
Excellent. Thanks! Wrt format, do you mean the full SaveData or the line 1 expansion of SaveData? I am new to jquery, ajax, and knockoutjs, so please feel free to pass on any advice you might have. The line 1 expansion is basically an implementation out of ignorance (let the framework do its thing and then fix the bad value).Gander
Yes, if that is the value that you want, then the answer below would be another way to do it. Good luck!Katricekatrina
K
3

Given the current issue with ko.toJS and dates, one option would be to create a dependentObservable containing the real value that you want the server to deal with.

Something like:

var viewModel = {
    startTimeForInput: ko.observable(),
    type: ko.observable(),
    durationInMinutes: ko.observable(),
    notes: ko.observable()
};

viewModel.startTime = ko.dependentObservable(function() {
    return this.startTimeForInput().toJSON();
}, viewModel);

ko.applyBindings(viewModel);

Now, when you call ko.toJSON you will get the startTime with the correct value that the server could use.

For older browsers, something like json2.js would include the .toJSON for Date objects.

Katricekatrina answered 11/5, 2011 at 16:45 Comment(1)
Thanks. That's a better workaround. It's too bad we have to work around it though.Gander
L
1

I had a problem with ko.toJSON() giving me a bad date format when the date was DateTime.MinValue.

Though probably not a fix for your problem, this fix worked for my ko.toJSON() date problem:

var postData = JSON.parse(JSON.stringify(ko.toJSON(viewModel)).replace(/\"1-01-01/g, "\"0001-01-01"));

ASP.Net WebMethod fails because ko.toJSON() produces different results for DateTime.MinValue

Lyautey answered 19/2, 2013 at 19:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.