0

I am new to knockout, and I am trying to create a function that I can bind to in my view, so that different input boxes will be bound to different elements of the array.

Unfortunately, the code that calls the function in knockout seems to happen before the array is populated. I am sure there is some simple way that I can fix this, but I have been trying for a while and just can't figure it out

(function () {

var BankingViewModel = function () {

    //data
    var self = this;
    self.safeFloatTotal = ko.observable(null);
    self.floatRecommendedValue = ko.observable(null);

    self.safeFloatDenominations = ko.observableArray();

        //populate the array 
        var safeFloatCash = bankingApi.client.getSafeFloatCash();
        safeFloatCash.done(function (d) {
            self.safeFloatDenominations(d);
        })


    self.GetNoteByDenomination = ko.computed( function () {
      //  return 1234; //will bind OK
        return self.safeFloatDenominations[1]; //length of the array is zero when this is called, so element is undefined

    });
}

$(document).ready(function () {
    var viewModel = new BankingViewModel();        
        ko.applyBindings(viewModel);        
});

})();

and in the view

<div class="row">
                        <div class="col-xs-6">
                            <input type="text" data-bind="value: GetNoteByDenomination" />
                            <label>£50</label>
                        </div>
                        <div class="col-xs-6">
                            <input type="text" data-bind="value: safeFloatTotal" />
                            <label>50p</label>
                        </div>
                    </div>

I need to be able to call the array after it is initialised, which is where I am stuck at the moment

1
  • You need to remove the api call from the viewmodel and add it in document.ready method, which onReady will populate your observablearray and the computed method will show the values in view. Other way is you can pass the api callback method to the viewmodel, which will pass the array values to the vm Commented Mar 26, 2015 at 13:37

2 Answers 2

2

If you're wanting to access the second element of an observable array, you have to execute the observable's function to get the underlying array:

self.GetNoteByDenomination = ko.computed(function () {
    return self.safeFloatDenominations().length > 1 ?
           self.safeFloatDenominations()[1] : "";
});

Doing self.safeFloatDenominations[1] will return undefined regardless of how many items are in the array.

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

3 Comments

The problem is that the binding happens before it has any data
@jazza1000 if you add more data to the self.safeFloatDenominations array, the computed will update accordingly. You don't have to worry about it not having data or not. As a test, just try returning self.safeFloatDenominations().length and you will see it works fine for updating.
@jazza1000 for example, you can see this array has no data, but if you add data it will update accordingly: jsfiddle.net/mufm7tnq -- When accessing elements of an array in a computed, you just have to make sure your computed handles the case where the array has no data.
0
var BankingViewModel = function(){
    var self = this;

    this.applyData = function(data){
        // map ur data response from api with the observablearray here
    };
}

$(document).ready(function(){
        var viewModel = new BankingViewModel();        
        ko.applyBindings(viewModel);   

        var safeFloatCash = bankingApi.client.getSafeFloatCash();
        safeFloatCash.done(function (d) {
             viewModel.applyData(d);
        })
});

Comments

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.