Jack
Jack

Reputation: 275

Knockout JS: checking for the existence of an observable in an IF binding

I'm rendering a similar block of HTML for several slightly different objects. They're 90% the same, but each one has some specific quirks that demand extra observables. I would like to render each of these mostly-similar items in a template block, but I'm running into problems with undefined objects.

Basically, I want to check for the existence of an observable object before rendering it in the template.

I am trying to do something like this:

<div data-bind="foreach: blocks">
<h2 data-bind="text: normalHeader"><h2>
<p data-bind="text: normalText"></p>
<!-- ko if: specialText --><p data-bind="text: specialText"></p><!-- /ko -->
</div>

So if specialText doesn't exist (not just has no value, but doesn't exist at all) for that iteration of blocks, ignore the conditional. The error I'm getting is:

Uncaught Error: Unable to parse bindings.
Message: ReferenceError: specialText is not defined;

From what I understand of Knockout's "if" binding, it should work if the object returns any kind of false-like value, like null or undefined, which means that the if binding should gracefully fail, which it definitely isn't.

Is there any way to make this work?

Upvotes: 20

Views: 24549

Answers (4)

Luca Cestola
Luca Cestola

Reputation: 23

You can do it by accessing through the object's indexer:

<!-- ko foreach: Items -->
    <strong data-bind="text: Foo"></strong>
    <br />
    <!-- ko if: $data["Bar"] -->
        <p data-bind="text: Bar"></p>
    <!-- /ko -->
<!-- /ko -->

Upvotes: 2

Oybek
Oybek

Reputation: 7243

You might use the following approach:

<!-- ko foreach: Items -->
    <strong data-bind="text: Foo"></strong>
    <br />
    <!-- ko if: $data.hasOwnProperty("Bar") -->
        <p data-bind="text: Bar"></p>
    <!-- /ko -->
<!-- /ko -->​

I've posted a working demo

Upvotes: 47

paulslater19
paulslater19

Reputation: 5917

<!-- ko if: typeof specialText != 'undefined' -->

Based on Oybek's solution, you could also do:

<!-- ko foreach: Items -->
    <strong data-bind="text: Foo"></strong>
    <br />
    <!-- ko if: "Bar" in $data -->
        <p data-bind="text: Bar"></p>
    <!-- /ko -->
<!-- /ko -->​

Example: http://jsfiddle.net/MecNx/56/

Upvotes: 10

soniiic
soniiic

Reputation: 2685

try this:

<!-- ko if: specialText != null -->

ko will recognise it as an expression rather than a value and so it should work as you want :)

Upvotes: 0

Related Questions