6

I can not quite figure out how to put an if statement inside a text binding.

<tbody data-bind="foreach: model.poCollection">
    <tr>
        <td>
            <input type="checkbox">
        </td>
        <td data-bind="text: RlseNbr"></td>
        <td data-bind="text: Clin"></td>
        <td data-bind="text: PrchOrdNbr"></td>
        <td data-bind="text: RqstnCntrlNbr"></td>
        <td data-bind="text: {(DtCntrctDlvry == '0') ? 'a' :'b'}"></td>
    </tr>

Not sure what I am doing wrong the moment I attempt to put the if statement in it the data is no longer displayed.

6
  • 2
    Try with text: DtCntrctDlvry() == '0' ? 'a' :'b' Commented Aug 28, 2015 at 19:03
  • To expand on @nemesv's comment. If DtCntrctDlvry (crazy name btw) is an observable, then it's never going to equal '0' because observables aren't strings, they're observables. Get the backing value by calling the observable as a function and then compare that with '0'. Commented Aug 28, 2015 at 19:14
  • 1
    @nemevs +1. Another way: text: ko.unwrap(DtCntrctDlvry) == '0' ? 'a' :'b' Commented Aug 28, 2015 at 19:45
  • @TSV's approach is preferred when you don't know at runtime if a property is an observable or not. Commented Aug 28, 2015 at 20:39
  • One more option if you don't want to have to worry about these syntax issues as often. blog.stevensanderson.com/2013/05/20/… Commented Aug 28, 2015 at 20:40

1 Answer 1

10

You haven't provided enough info, but we can safely assume one of two situations:

  1. Plain properties: DtCntrctDlvry = 0; or
  2. Observables: DtCntrctDlvry = ko.observable(0)

Binding handlers don't care which it is if you do simple bindings, e.g.:

<span data-bind="text: DtCntrctDlvry"></span>

But they do care if you start putting logic in there. Above situations respectively require:

  1. Plain properties:

    <span data-bind="text: DtCntrctDlvry === 0 ? 'a' : 'b'"></span>
    
  2. Observables:

    <span data-bind="text: DtCntrctDlvry() === 0 ? 'a' : 'b'"></span>
    

In any case, please see my answer to another question where I argue that you would be off even better if you wrap the logic inside a computed, e.g.:

var ViewModel = function() {
  var self = this;
  self.DtCntrctDlvry = ko.observable(0);
  self.DtCntrctDlvryText = ko.computed(function() {
    return self.DtCntrctDlvry() === 0 ? "a" : "b";
  });
}

And bind like this:

<span data-bind="text: DtCntrctDlvryText"></span>

PS. Some footnotes:

  1. Do you realize you're using == where you might prefer ===?
  2. Any reason you're writing '0' (zero, but as a string) instead of 0 (as a number)?

In my answer I've assumed the for both cases you meant to use the latter. If not, you may have to tweak my solution for that.

Sign up to request clarification or add additional context in comments.

3 Comments

You can use ko.unwrap to avoid the issue of plain properties and observables
this really helped me also! what made it weird is the difference () can make. :D
@AceMark Observables are functions. Called without parameters they are a "getter", called with one parameter they are a "setter". Only in 'simple' bindings can you leave them off because Knockout will infer them.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.