Search code examples
javascriptknockout.jsprototypeknockout-validation

Using Knockout Validation with knockout.utils.extend


How can I use ko.validation with ko.utils extend?

This is what ive tried and I think as im fairly new to JS I might be making a fundamental error (errors im getting are in comments):

var Customer = function (data) {
    var cus = this;
    cus.FirstName = ko.observable();
    cus.LastName = ko.observable();
    cus.Email = ko.observable();//.extend({ required: true, email: true });
    // above line causes 'Uncaught TypeError: observable.extend is not a function'

    //extenders
    this.cleanData = data;// copy of original Customer
    this.initData(data);//call your prototype init function 

};

// Extend the Customer object to init with data & also so we can revert back to original if user cancel's 
ko.utils.extend(Customer.prototype, {
    initData: function (data) {
        this.FirstName(data.FirstName);
        this.LastName(data.LastName);
        this.Email(data.Email).extend({ required: true, email: true });
        // above line causes 'this.Email(...).extend is not a function'
    },
    revert: function () {
        this.initData(this.cleanData);
    }
});

This code below works fine if I remove the ko.utils.extend (loosing init/revert in the process) in the Customer object:

    var Customer = function (data) {
    var cus = this;
    cus.FirstName = ko.observable(data.FirstName);
    cus.LastName = ko.observable(data.LastName);
    this.Email(data.Email).extend({ required: true, email: true });// works fine - but weve lost 'ko.utils.extend' functionality
};

Unfortunately as I say im loosing the init & revert which I need.

So what im asking is am I making a daft mistake here and can someone please explain how this should work.


Solution

  • The fault is just in your initData method. This line is OK:

    cus.Email = ko.observable();//.extend({ required: true, email: true });
    

    It is this bit that doesn't work:

    this.Email(data.Email).extend({ required: true, email: true });
    

    You can use extend via the ko.observable function but you cannot then use .extend on the result of setting the observable. To fix your code, do:

    // Set it
    this.Email(data.Email);
    // Then extend it
    this.Email.extend({ required: true, email: true });
    

    Here's a fiddle to show you:

    http://jsfiddle.net/2wLL3exc/