Rasmus Eskesen
Rasmus Eskesen

Reputation: 246

Binding text value in html element using knockout

I have a popup div containing an error message that I want to generate at the time the popup actually pops up. In my popup div I have a ptag where its text is databinded to a function that returns a string (the error message). I've done similar things before with much success, but this time I'm struggling to successfully bind the value properly.
The HTML div (ignore the jQuery Mobile attributes):

<div data-role="popup" id="ErrorRowValidation" data-overlay-theme="b" data-theme="a" class="standarddialog" data-dismissible="false">
    <div data-role="header" data-theme="a" class="ui-corner-top">
        <h1>Error</h1>
    </div>
    <div data-role="content" data-theme="d" class="ui-corner-bottom ui-content">
        <p data-bind="text: $root.getModelErrorText.bind($root)" class="validationError"></p>
        <a href="#" data-role="button" data-icon="check" data-inline="true" data-bind="click: $root.correctRowValue.bind($root)" data-theme="a">Edit</a>
        <a href="#" data-bind="click: $root.undoValidation.bind($root)" data-role="button" data-icon="delete" data-inline="true" data-rel="back" data-theme="a">Undo changes</a>
    </div>
</div>

My JavaScript (actually typescript) function successfully returns a proper string, so that's not the problem, but here it is anyway:

public getModelErrorText(): string {
    return lang.translateNewlineString(this.model.ErrorText());
}

I think I'm not binding the text value correctly when writing data-bind="text: $root.getModelErrorText.bind($root)"..?
With the code above I get function() {[native code]} as a result. I've also tried doing data-bind="text: $root.getModelErrorText()" with no success; the page won't even load then. I'm new to using Knockout, so I don't really know what I'm doing... Any suggestions are very welcome!

Upvotes: 0

Views: 2098

Answers (1)

Hans Roerdinkholder
Hans Roerdinkholder

Reputation: 3000

I think I'm not binding the text value correctly when writing data-bind="text: $root.getModelErrorText.bind($root)"

Indeed, this is not correct and will result in function() {[native code]}

bind doesn't execute your function, it just creates a new function with a different execution context (this may or may not be slightly improperly formulated by me, but I am 100% sure the function is not executed).

data-bind="text: $root.getModelErrorText()" SHOULD work, if all other things work. So I'm not 100% sure why this doesn't work for you. We'd need additional information to debug that (more code, e.g. your viewModel, html and applyBindings call). One good bet, is that this in your function getModelErrorText is not set to the viewModel when executed through the binding. You can easily see if this is the problem, by transforming the function to fat arrow syntax, like this:

public getModelErrorText = () => {
    return lang.translateNewlineString(this.model.ErrorText());
}

This should guarantee that this points to your viewModel.

If this does not resolve the problem, can you edit your post with the code I mentioned above, and I will edit my answer as well.

Edit:

Another possibility, is that this.model or this.model.ErrorText is not yet a truthy value (e.g. it is null or undefined) when the bindings are applied. In that case, this.model.ErrorText() will fail, since you are trying to execute a function (observable) that does not yet exist, because it is initialized at a later point in time. Make sure the default values in your viewModel have a properly set model with ErrorText function/observable. When your page doesn't load, try looking in the developer tools -> console to see if Knockout gives you an error message. It will probably be helpful if you post it here.

Upvotes: 1

Related Questions