Knockout ViewModel isValid error when using Knockout validation plugin

Cam Langsford picture Cam Langsford · May 29, 2013 · Viewed 12.7k times · Source

I'm new to using knockout and I'm trying to use the knockout validation plugin along with the mapping plugin. I'm having an issue with the isValid function on the view model object. According to the documentation isValid should return a bool to determine whether any of the observables on the view model are in valid but when I call it I get an error saying that isValid is not a function. However if I call isValid on the observables themselves it works fine. The problem is I'm using the mapping plugin with some dynamic data objects that I get from the server so I don't necessarily know the names of the observables I need to validate so it's not feasible to validate them individually. The example below is simplified but in the real implementation I don't know the names of the observables. Maybe I've just missed some documentation?

Thanks for your time.

This does work

    var dataItem = { FirstName: '', LastName: '', Age: '', Email: '' }


    var viewModel = function(data) {

        var self = this;
        this.Email = ko.observable().extend({ email: true });
        this.LastName = ko.observable().extend({ required: true });
        this.Age = ko.observable().extend({ required: true, min: 0 });
        this.saveClick = function () {

            if (!self.Email.isValid() || !self.Age.isValid() || !self.LastName.isValid()) {
                alert('Not valid');
            else {

                alert('Valid');
            }
        };
        this.cancelClick = function () {

            ko.mapping.fromJS(dataItem, null, this);
        }

        ko.mapping.fromJS(data, {}, this);
    };

    var viewModelInstance = new viewModel(dataItem);
    ko.applyBindings(viewModelInstance, document.getElementById('bindingDiv'));

But this doesn't work

        var dataItem = { FirstName: '', LastName: '', Age: '', Email: '' }


        var viewModel = function(data) {

            var self = this;
            this.Email = ko.observable().extend({ email: true });
            this.LastName = ko.observable().extend({ required: true });

            this.Age = ko.observable().extend({ required: true, min: 0 });
            this.saveClick = function () {
                //TODO: according to the documentation you should be able to just
                //check self.isValid() but that throws an error that there is no
                //such method on the object? dunno why.
                if (!self.isValid()) {
                    alert('Not Valid');
                }
                else {
                    alert('Valid');
                }
            };
            this.cancelClick = function () {

                ko.mapping.fromJS(dataItem, null, this);
            }

            ko.mapping.fromJS(data, {}, this);
        };

        var viewModelInstance = new viewModel(dataItem);
        ko.applyBindings(viewModelInstance, document.getElementById('bindingDiv'));

Answer

Cam Langsford picture Cam Langsford · Jun 6, 2013

Just thought I'd post the actual code I needed to use. Thanks to ragnarok56 for pointing me in the right direction. I'd obviously spent too little time on the documentation.

I just added this line of code above the call to check isValid() on the view model

var result = ko.validation.group(viewModelInstance, { deep: true });