I have two functions generate
and test
. When the user clicks a button generate
is called which then calls test
function. I receive the following error:
Pass a function that returns the value of the ko.computed.
The error is thrown on this line in the test function.:
var unmapped = ko.mapping.toJS(this);
this
is my viewmodel with ko.observable properties.
Here are the two functions. If I move the content of test
function to generate
everything works fine but I need the logic to be in two different functions. What can I do?
I am very stuck here. Any help will be greatly apreciated.
generate = function () {
if (!omega.validatableFranchiseGeneration.validate()) {
return false;
}
omega.franchiseInfo.IsForGeneration(true);
test();
}
var test = function () {
getIpsAndPorts();
for (var i = 0; i < omega.franchiseInfo.LanguagesInfoViewModel().length; i++) {
if ($.isArray(omega.franchiseInfo.LanguagesInfoViewModel()[i].SubMenuItemsViewModel)) {
omega.franchiseInfo.LanguagesInfoViewModel()[i].SubMenuItemsViewModel = omega.franchiseInfo.LanguagesInfoViewModel()[i].SubMenuItemsViewModel[0];
}
}
var unmapped = ko.mapping.toJS(this);
var jsonData = ko.toJSON(unmapped);
$.ajax({
url: "/franchise/Save",
type: "POST",
// data: ko.toJSON({ folderName: FolderName }),
data: { franchiseInfoViewModel: jsonData },
//traditional: true,
//contentType: "application/json; charset=utf-8",
dataType: 'json',
success: function (data, textStatus, xhr) {
window.location.href = data.redirectToUrl;
},
error: function (request, status, error) {
jsonValue = jQuery.parseJSON(request.responseText);
omega.franchiseInfo.errorMessages([]);
for (var i = 0; i < jsonValue.errorMessages.length; i++) {
omega.franchiseInfo.errorMessages.push({ errorMessage: ko.observable(jsonValue.errorMessages[i].ErrorMessage) });
}
for (var i = 0; i < omega.franchiseInfo.LanguagesInfoViewModel().length; i++) {
InitializeViewLanguagesInfo(omega.franchiseInfo.LanguagesInfoViewModel()[i]);
}
}
});
}
Without seeing all your code this is hard to be sure, but if the code (as is) works when directly included in generate, then I'd be willing to bet that
this
is not what you think it is in thetest
function.this
has a different meaning inside thetest
function than it did insidegenerate
.Fire up Chrome or Firebug and set a breakpoint on the
var unmapped = ko.mapping.toJS(this);
line. Run your program and when the breakpoint hits go to the Console and look atthis
. Is it your ViewModel?If
this
is what you expect insidegenerate
you could always calltest
like this:This will explicitly set the context of
this
for the method invocation.Another option is to set a
self
variable inside your ViewModel. This is usually done at the top and looks like:var self = this;
. By creating this variable you can then referenceself' inside any functions within the outer "function" scope, and not have to worry about the value of
this` fluctuating.--
Here is a simple fiddle to simulate what I think is happening: http://jsfiddle.net/jearles/aLFWe/
Open Chrome or Firebug console and look at the logged objects. Note that
Window
was the logged object when I just calledupdatea()
, but wasObject
in the original click function and when I calledupdateb.apply(this)
orupdatec()
(which referencedself
).