Getting "Cannot read property 'nodeType' of null" when calling ko.applyBindings

Javascriptknockout.js

Javascript Problem Overview


I have this knockout code:

function Task(data) {
    this.title = ko.observable(data.title);
    this.isDone = ko.observable(data.isDone);
}

function TaskListViewModel() {
    // Data
    var self = this;
    self.tasks = ko.observableArray([]);
    self.newTaskText = ko.observable();
    self.incompleteTasks = ko.computed(function() {
        return ko.utils.arrayFilter(self.tasks(), function(task) { return !task.isDone() });
    });

    // Operations
    self.addTask = function() {
        self.tasks.push(new Task({ title: this.newTaskText() }));
        self.newTaskText("");
    };
    self.removeTask = function(task) { self.tasks.remove(task) };
}

ko.applyBindings(new TaskListViewModel());

This html:

<head>
    <script type="text/javascript" src="jquery-1.7.1.min.js"></script>
    <script type="text/javascript" src="knockout-2.0.0.js"></script>
    <script type="text/javascript" src="script.js"></script>
</head>
<body>
    <h3>Tasks</h3>

    <form data-bind="submit: addTask">
        Add task: <input data-bind="value: newTaskText" placeholder="What needs to be done?" />
        <button type="submit">Add</button>
    </form>

    <ul data-bind="foreach: tasks, visible: tasks().length > 0">
        <li>
            <input type="checkbox" data-bind="checked: isDone" />
            <input data-bind="value: title, disable: isDone" />
            <a href="#" data-bind="click: $parent.removeTask">Delete</a>
        </li> 
    </ul>

    You have <b data-bind="text: incompleteTasks().length">&nbsp;</b> incomplete task(s)
    <span data-bind="visible: incompleteTasks().length == 0"> - it's beer time!</span>
</body>

The example is the same as the one found on the Knockout website, but when I run it, it returns this message on Chrome Fire Bug:

> Uncaught TypeError: Cannot read property 'nodeType' of null

This one is related to the knockout file and to this line of my script:

ko.applyBindings(new TaskListViewModel());

And this error is pointing to this line (1766) on knockout:

var isElement = (nodeVerified.nodeType == 1);

What am I doing wrong?

Javascript Solutions


Solution 1 - Javascript

This problem was happening because I was trying to bind an HTML element before it was created.

My script was loaded on top of the HTML (in the head) but it needed to be loaded at the bottom of my HTML code (just before the closing body tag).

Thanks for your attention James Allardice.

A possible workaround is using defer="defer"

<script src="script.js" type="text/javascript" defer="defer"></script>

Use this if the script is not going to generate any document content. This will tell the browser that it can wait for the content to be loaded before loading the script.

Further reading.

Hope it helps.

Solution 2 - Javascript

You might want to consider using the jquery ready handler for this

$(function() {
   function TaskListViewModel() {
   ...
   ko.applyBindings(new TaskListViewModel());
});

Then you achieve two things:

  1. Avoid polluting the global namespace
  2. Knockout binding occurs AFTER the DOM is created. You can place your javascript wherever it is suited for organization.

See http://api.jquery.com/ready/

Solution 3 - Javascript

if you have jQuery put apply binding inside onload so that knockout looks for the DOM when DOM is ready.

$(document).ready(function(){
    ko.applyBindings(new TaskListViewModel());
});

Solution 4 - Javascript

You have a simple spelling mistake:

self.addTask = fuction() {

Should be:

self.addTask = function() { //Notice the added 'n' in 'function'

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser745235View Question on Stackoverflow
Solution 1 - Javascriptuser745235View Answer on Stackoverflow
Solution 2 - JavascriptJames KesslerView Answer on Stackoverflow
Solution 3 - JavascriptJhankar MahbubView Answer on Stackoverflow
Solution 4 - JavascriptJames AllardiceView Answer on Stackoverflow