Water Cooler v2 Water Cooler v2 - 1 month ago 6
Javascript Question

How to get this simple one-way binding with knockout to work?

I am learning knockout and this is my first ever example of it, so please be gentle.

I just want a one-way binding from the model to the textboxes, i.e, whatever is in the model must be displayed in the text boxes. I do not want to create observables yet.

Here is what I have, but when I run this code, the text boxes do not contain the model values, and the console reports an error:


TypeError: c is null



Here is my code:

1.html

<html>
<head>
<meta charset="utf-8"/>
<script type='text/javascript' src='knockout-3.4.0.js'></script>
<script type='text/javascript' src='1.js'></script>
</head>

<form id = "frm" name = "frm">
<fieldset>
<legend>Your friend's basic information</legend>

<div>
<label for = "FirstName">First Name</label>
<input type = "text" name = "FirstName" id = "txtFirstName" data-bind = "value: friend.firstName" />
</div>

<div>
<label for = "LastName">Last Name</label>
<input type = "text" name = "LastName" id = "txtLastName" data-bind = "value: friend.lastName" />
</div>
</fieldset>

</form>
</html>


1.js

var model =
{
friend :
{
firstName : 'Sathyaish',
lastName : 'Chakravarthy'
}
};

ko.applyBindings(model);


It looks like knockout isn't able to bind a nested property. Since the property I am binding to isn't directly a member of the
model
object, but it is instead nested inside
model.friend
, it isn't able to bind it.

Surely it can't be that I cannot have a hierarchical model and that I can only bind if the properties are top-level members of the
model
object?

I am most likely doing something wrong with the syntax.

Answer

If you don't pass rootElement to apply bindings, it's going to use window.document.body. However, if you script is loaded in head section, the body is not available at that moment. So you need to move your 1.js loading inside the body like this:

<html>
    <head>
        <meta charset="utf-8"/>
        <script type='text/javascript' src='https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-debug.js'></script>

    </head>

    <body>
    <form id = "frm" name = "frm">
        <fieldset>
            <legend>Your friend's basic information</legend>

            <div>
                <label for = "FirstName">First Name</label>
                <input type = "text" name = "FirstName" id = "txtFirstName" data-bind = "value: friend.firstName" />
            </div>

            <div>
                <label for = "LastName">Last Name</label>
                <input type = "text" name = "LastName" id = "txtLastName" data-bind = "value: friend.lastName" />
            </div>
        </fieldset>

    </form>
    <script type='text/javascript' src='1.js'></script>
    </body>
</html>