Hayden Chambers
Hayden Chambers

Reputation: 747

knockout console log and observable undefined

I've seen comments on console logging observables but it doesn’t seem to work for me. Additionally my app isn't starting up with a the default var that I was expecting. The two questions are together because I suspect they're related somehow.

Here is the fiddle.

HTML

<select data-bind="options: widgets, optionsText: 'name', value: current_widget, optionsCaption: 'Choose...'"></select>
<input data-bind="value: current_widget() ? current_widget().name : 'nothing'" />

Javascript

var cdta = {};
$(document).ready(function(){

    cdta.widgets_data = [{ "name": "foo", "id": "1"},{ "name": "bar", "id": "2"},{ "name": "bash", "id": "3"},{ "name": "baq","id": "4"}];

    cdta.local = {};
    cdta.local.current_widget = { "name": "foo", "id": "1"};

    alert('current_widget starting value should be: ' + cdta.local.current_widget.name);

    function app() {
        var self = this;

        //widgets
        self.widgets = ko.observableArray(cdta.widgets_data);

        // which widget to display from a local source
        alert('about to asign a current_widget named:' + cdta.local.current_widget.name);
        self.current_widget = ko.observable(cdta.local.current_widget);
    }
    ko.applyBindings(new app());

    alert('after applying bindings name of current widget: ' + current_widget().name);
    //expecting foo
    //but doesn’t alert because current_widget isnt defined
});

Upvotes: 0

Views: 3305

Answers (2)

Roman Bataev
Roman Bataev

Reputation: 9361

There are couple of issues in your code.

  1. current_widget is a property of app, so you need to do something like this

    var app = new app();
    ko.applyBindings(app);
    alert('after applying bindings name of current widget: ' + app.current_widget().name);
    
  2. Since you are using value and optionsCaption bidnings, knockout will set the observable that's bound to value to undefined by default. If you remove optionsCaption binding it will work. If you need optionsCaption and you need to select initial value, you will have to reset it after applying bindings:

    var app = new app();
    ko.applyBindings(app);
    app.current_widget(cdta.widgets_data[0]); //you have to select an object from the array, not a completely unrelated object cdta.local.current_widget
    alert('after applying bindings name of current widget: ' + app.current_widget().name);
    

UPDATE: I was wrong on #2. You don't have to reset value after applying bindings. The real problem is that you use completely unrelated object (not from the array) for initial value. This will fix the issue:

cdta.local.current_widget = cdta.widgets_data[0];

Upvotes: 2

AlfeG
AlfeG

Reputation: 1473

But variable/method current_widget indeed undefined. KnockoutJS doesn't generate gloabal variables.

If You want to access viewModel data outside of viewModel, then You need to store it somewhere(variable, window, etc).

var cdta = {};
$(document).ready(function(){    
    //...    
    function app() {
       //...
    }
    window.app = new app();
    ko.applyBindings(window.app);

    alert('after applying bindings name of current widget: ' 
      + window.app.current_widget().name);
    //expecting foo
});

Upvotes: 1

Related Questions