Search code examples
jqueryknockout.jsknockout-mapping-plugin

In knockoutjs “Uncaught Error: Unable to parse bindings.” error, but code works


I am working with knockout js mapping, while try to execute sample i got the console error.

Uncaught Error: Unable to parse bindings. Message: ReferenceError: loadUserData is not defined; Bindings value: click: loadUserData

Here the code,

<form action="#" method="post">
    <p>First name: <input data-bind='value: firstName' /></p>
    <p>Last name: <input data-bind='value: lastName' /></p>
    <div>
        Your favorite food:
        <select data-bind='options: activities, value: favoriteHobby'></select>
    </div>
    <p><button data-bind='click: loadUserData'>Load data</button></p>
    <p><button data-bind='click: saveUserData'>Save Data</button></p>
</form>
<script>
    function PersonViewModel() {
        var self = this;
        self.firstName = "";
        self.lastName = "";
        self.activities = [];
        self.favoriteHobby = "";
        self.loadUserData = function () {
            $.getJSON("/get-user-data.json", function (data) {
                var viewModel = ko.mapping.fromJS(data);
                ko.applyBindings(viewModel);
            });
        }
        self.saveUserData = function () {
            var data_to_send = { userData: ko.toJSON(self) };
            $.post("/save-user-data", data_to_send, function (data) {
                alert("Your data has been posted to the server!");
            }).fail(function () {
                alert("Ensure the Url before save the data");
            });
        }
    }
    ko.applyBindings(new PersonViewModel());
</script>

get-user-data.json

{
   "firstName": "John",
   "lastName": "Smith",
   "activities": [ "Golf", "Kayaking", "Web Development" ],
   "favoriteHobby": "Golf"
}

while click load data button the error occuring, but sample works, how to clear this error.


Solution

  • As @user3297291 pointed out, you can't call ko.applyBindings twice. Instead, make the properties of your view model knockout observables and knockout will automatically update your UI when they change:

    function PersonViewModel() {
        var self = this;
        self.firstName = ko.observable();
        self.lastName = ko.observable();
        self.activities = ko.observableArray();
        self.favoriteHobby = ko.observable();
        self.loadUserData = function () {
            return $.getJSON("/get-user-data.json", function (result) {
                self.firstName(result.firstName)
                    .lastName(result.lastName)
                    .favoriteHobby(result.favoriteHobby)
                    .activites(result.activities);
            });
        }
    }
    ko.applyBindings(new PersonViewModel());