1

I have a ViewModel like this:

    function FooViewModel() {
            var self = this;
            self.prevPage = ko.observable();
            self.nextPage = ko.observable();
            self.totalItems = ko.observable();
            self.totalPages = ko.observable();
            $.ajax({
                type: 'GET',
                url: 'http://localhost:xxxx/api/',
                datatype: 'json',
                success: function (data) {
                    // 
                },
                error: function (err){
                    //
                },
                complete: function(request){
                    //Pagination information in the responseheader.
                    pagingheader = request.getResponseHeader('X-Pagination');
                    var json = JSON.parse(pagingheader);
                    self.prevPage(json["PrevPageLink"]);
                    self.nextPage(json["NextPageLink"]);
                    self.totalItems(json["TotalCount"]);
                    self.totalPages(json["TotalPages"]);
                    console.log(self.totalPages()) // Writes the correct number.
                }
            });
        }
var vm;
$(document).ready(function () {
            vm = new FooViewModel();
            ko.applyBindings(vm);
            // Here I want to access the different properties of the ViewModel.
            console.log(typeof vm.totalPages) // writes function
            console.log(typeof vm.totalPages()) //writes undefined
            console.log(vm.totalPages()); // Writes undefined

        });

I've looked at this knockout.js access viewModel in javascript function outside viewModel's scope.

Is there a way I can access the ViewModels properties in document.ready ?

3
  • 3
    If you are able to print the function definition of totalPages, it means that already you are able to access the viewModel. But the problem here is the ajax request you are making is not yet complete and the values are not yet initialized. Commented Apr 23, 2014 at 9:47
  • Thanks. Is there a way to wait for the ajax request to complete, and then get the values?
    – CF256
    Commented Apr 23, 2014 at 10:16
  • pass a callback function to your viewModel when you create a new object from it, and let the complete call that function?
    – Major Byte
    Commented Apr 23, 2014 at 10:25

1 Answer 1

2

You are trying to access properties of your view model before they were set, as was mentioned in the comments. I think the better way to implement this is to define a load function in your viewModel which will return promise.

function FooViewModel() {
    var self = this;
    self.prevPage = ko.observable();
    self.nextPage = ko.observable();
    self.totalItems = ko.observable();
    self.totalPages = ko.observable();
    self.load = function() {
        return $.ajax({
            type: 'GET',
            url: 'http://localhost:xxxx/api/',
            datatype: 'json',
            success: function (data) {
                // 
            },
            error: function (err){
                //
            },
            complete: function(request){
                //Pagination information in the responseheader.
                pagingheader = request.getResponseHeader('X-Pagination');
                var json = JSON.parse(pagingheader);
                self.prevPage(json["PrevPageLink"]);
                self.nextPage(json["NextPageLink"]);
                self.totalItems(json["TotalCount"]);
                self.totalPages(json["TotalPages"]);
                console.log(self.totalPages()) // Writes the correct number.
            }
        });
    }
}

Notice that $.ajax returns jquery promise that has.

And in your document ready, you can hook up to the done handler of the returned promise.

var vm;
$(document).ready(function () {
    vm = new FooViewModel();
    vm.load().done(function() {
        ko.applyBindings(vm);
        console.log(typeof vm.totalPages) // writes function
        console.log(typeof vm.totalPages()) //writes undefined
        console.log(vm.totalPages()); // Writes undefined
    });
});

The jqXHR objects returned by $.ajax() as of jQuery 1.5 implement the Promise interface https://api.jquery.com/jQuery.ajax/

Not the answer you're looking for? Browse other questions tagged or ask your own question.