I have a knockout pureComputed observable that is supposed to return if a account number is valid. First it checks if the field is empty. (returns false) Then it checks to see if the account number has changed from what was loaded. (returns true) Finally it will run the ajax call to get the account info. If successful it will set the ErrorMessage from the object and the Customer info. Then it is supposed to return true or false based on the ErrorMessage. If unsuccessful it will set the ErrorMessage and return false.
self.isAccountValid = ko.computed(function () {
if (!self.account()) {//If not complete mark as InValid
self.accountError("Account Number Incomplete.")
return false;
} else if (vm.account == self.account()) {
self.accountError("");
return true;
} else {
var deferred = $.Deferred();
return $.ajax({
url: '/Order/NumberValidation',
data: { account: self.account() }
}).success(function (data) {
self.accountError(data.ErrorMessage);
//Set customer info properties
self.setCustomerInfo(data);
//Set success or warn icon based on error message field
var isValid = !data.ErrorMessage;
deferred.resolve(isValid);
return deferred;
}).error(function (data) {
//Set error message for invalid account
self.accountError("Server error. Please try again in a few minutes.");
//Set warning icon
return false;
})
}
}).extend({ async: ko.observable() });
They extend is a method I found to allow the computed to wait on the ajax call:
ko.extenders.async = function (nonObservableComputed, observableResult) {
nonObservableComputed.subscribe(function (result) {
jQuery.when(result).then(observableResult);
});
return observableResult;
}
This is setting the other data correctly on success, but the return of !data.ErrorMessage which evaluates to false if looking at it through debug is not what is set for the value of isAccountValid. Instead it is being set to the whole data object even though I am trying to return just the boolean.
myViewModel.isAccountValid()
Object {FirstName: null, LastName: null, StreetAddress: null, City: null, State: null…}
City: null
ErrorMessage: "Sequence contains no matching element"
FirstName: null
LastName: null
PhoneNumber: 0
State: null
StreetAddress: null
ZipCode: 0
One problem is that you're using a
pureComputed
for a function with side effects.You also have an extra c in
acccountError
in your success section.The extender is pretty horrible. It becomes trivial if you pass it the computed you want to use instead of its type, and don't need the added
inProgress
member.Demo: http://jsfiddle.net/sp160tan/1/
Update Pretty sure your problem is that you're returning the ajax result rather than the deferred. Also, the success and error callbacks don't need to return anything; their return values are not used. This could be a source of confusion.