Terje Nygård Terje Nygård - 29 days ago 8
Javascript Question

Knockout.JS : self.myObservable is not a function, issues with code order

I have page using knockout, which has a searchfield, selectedvalue from a dropdown, and pagenumber..

All these are initialized at set to defaultvalues, especially for first run / page access..

The problem is that i dont understand why i'm getting the following error

"self.selectedTeamId is not a function()"


I know.. this has to be something with the "order of things", so that when it's being used, it has NOT been initialized yet.

Can someone correct my mistake ?

CODE :

$(document).ready(function() {

var ViewModel = function() {
var self = this;
self.photos = ko.observableArray();
self.selectedTeamId = ko.observable(0);
self.searchString = ko.observable('');
self.pageNumber = ko.observable(1);

self.clearFilters = function() {
self.searchString(''); // set default to ''
self.selectedTeamId(0); // set default to 0
self.pageNumber(1); // set default to 1
self.getPhotos();
};

self.getPhotos = function () {
var photoParams = "?teamId=" + self.selectedTeamId() + "&search=" + encodeURIComponent(self.searchString()) + "&pageNumber=" + self.pageNumber();
$.get("api/Photo/GetPhotos" + photoParams,
function(data) {
self.photos(data);
}, "json");
};
};
var photosModel = new ViewModel();

ko.applyBindings(photosModel, document.getElementById("photoarchive"));

// THE NEXT LINE GIVES THE ERROR (self.selectedTeamId())
var photoParams = "?teamId=" + self.selectedTeamId() + "&search=" + encodeURIComponent(self.searchString()) + "&pageNumber=" + self.pageNumber();
$.get("api/Photo/GetPhotos" + photoParams,
function(data) {
photosModel.photos(data);
}, "json");
});

Answer

self is a variable which is local to your ViewModel function. It isn't accessible outside of that function.

As you're storing your ViewModel within your photosModel variable, you can instead access the selectedTeamId observable with:

photosModel.selectedTeamId()

You'll need to do the same with self.searchString() and self.pageNumber().

That said, however, you may as well just call photosModel.getPhotos() instead of duplicating the entire function outside of the ViewModel scope.