knockout.jsdurandal

Unable to Process binding


I am currently trying to create a list of people with this model

{firstName: "", lastname: "", address:""}

in a multi value Select.

In my viewModel I have a field called selectedItem and I set that to null because there is nothing selected to start with.

On my view I am able to set selectedItem to the item that is selected in my Select element, I then want to display the properties of the selectedItem on screen, the way I tried this is

<p data-bind="text: selectedItem.firstName">First Name</p>
<p data-bind="text: selectedItem.lastName">Last Name</p>
<p data-bind="text: selectedItem.address">Address</p>

but it says this in the console

Unable to process binding "text: function (){return selectedItem.firstName }"
Message: Cannot read property 'firstName' of undefined;

which stops all the other bindings from happening (I have a delete button further on). A screen shot for context, I'm terrible at describing things The console message seems to indicate the viewModel is processed after the page is or something to that effect cause otherwise it would be complaining about null values right??? Is there anyway to have the binding be ignored if selectedItem is undefined/null or am I trying this the wrong way?

Edit: here's a jsFiddle but I noticed it doesn't behave 100% the same as the node-webkit environment I am using, it receives all the data of the first item in the list but then nothing else does


Solution

  • First you have to make selectedItem to an observable to be notified when it is changes:

    self.selectedItem = ko.observable(null);
    

    Then you need to handle the case when the selectedItem is empty in your bindings with:

    <div class="col-md-8">
        <p data-bind="text: selectedItem() && selectedItem().firstName">First Name</p>
        <p data-bind="text: selectedItem() && selectedItem().lastName">Last Name</p>
        <p data-bind="text: selectedItem() && selectedItem().address">Address</p>
    </div>
    

    However a more proper solution would be to use the with binding which takes care of the case when the selectedItem is null and also reduces the repetition:

    <div class="col-md-8" data-bind="with: selectedItem">
        <p data-bind="text: firstName">First Name</p>
        <p data-bind="text: lastName">Last Name</p>
        <p data-bind="text: address">Address</p>
    </div>
    

    Demo JSFiddle.