2

The following java-script which defines the MyViewModel object with a property "text" and a function "save".

<script type="text/javascript">
    function MyViewModel() {
        this.text = ko.observable('');
    }

    MyViewModel.prototype.save = function () {
        alert(this.text()); // Works fine
        var data = ko.ToJSON(this); // Error: Object doesn't support this property or method ?
        $.ajax({
            type: 'POST',
            url: '/Person/Save',
            data: data,
            contentType: 'application/json',
            success: function (data) {
                alert(data);
            }
        });
    };
</script>

<script type="text/javascript">
    $(function () {
        var viewModel = new MyViewModel()
        ko.applyBindings(viewModel);
    });
</script>


And the following button defined:

<button data-bind="click: save">SAVE</button>


Result when the button is clicked:

  • Accessing a property using this.text() works fine
  • Converting the java-script object to a JSON object : ko.ToJSON(this) does not work and throws an error: "Error: Object doesn't support this property or method"

Probably something trivial is missing or wrong, but I can't see it. Any tips ?

Stef Heyenrath
  • 9,335
  • 12
  • 66
  • 121
  • That's a nice pattern to be using - and it will work if you use `toJSON` rather than `ToJSON` (Knockout fully supports this pattern, you just had a typo in your code). – Sean Vieira Dec 02 '11 at 22:46

2 Answers2

4

Knockout doesn't have a ToJSON method - it does have a toJSON method though:

function MyViewModel() {
    this.text = ko.observable('');
}

MyViewModel.prototype.save = function () {
    alert(this.text()); // Works fine
    var data = ko.toJSON(this); // Works fine too
    $.ajax({
        type: 'POST',
        url: '/Person/Save',
        data: data,
        dataType: 'json',
        success: function (data) {
            alert(data);
        }
    });
};
Sean Vieira
  • 155,703
  • 32
  • 311
  • 293
  • Sean thanks for your help. (Sometimes it is very simple). For some reason javascript Intellisense was not working correctly, so I didn't see this error. – Stef Heyenrath Dec 03 '11 at 10:52
  • 1
    Add the following references in the starting of your javascript file /// – akeeseth Dec 07 '12 at 10:29
0

You have defined your view model as a function (a class, if you like):

function MyViewModel() {
    this.text = ko.observable('');
}

Instead, you should define it as a var (an object):

var MyViewModel = {
    text: ko.observable('');
}

You should then find that the following works fine:

var data = ko.ToJSON(MyViewModel);
Mark Robinson
  • 13,128
  • 13
  • 63
  • 81
  • I see, but I don't understand why I'm able to access a property from an object, but not the object itself? – Stef Heyenrath Dec 02 '11 at 12:04
  • I think it is to do with the difference between the first being a function declaration and the second being a function expression. This may help: http://stackoverflow.com/questions/5754538/javascript-object-literal-notation-vs-plain-functions-and-performance-implicatio – Mark Robinson Dec 02 '11 at 15:03
  • 1
    @MarkRobinson - actually, Knockout supports using `this` in the way Stef is using it - Knockout simply does not have a `ToJSON` method (the method he's looking for is `toJSON`. – Sean Vieira Dec 02 '11 at 22:47
  • It makes no difference declaring as inline object or as a method. It only matters if you need to use this, say for a ko.dependable as in-line objects don't support this as keyword. – Simon Halsey Dec 04 '11 at 04:50