Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ko.validation.group unexpected null entry #99

Closed
tomalec opened this issue Jul 18, 2012 · 5 comments
Closed

ko.validation.group unexpected null entry #99

tomalec opened this issue Jul 18, 2012 · 5 comments
Assignees
Labels
Milestone

Comments

@tomalec
Copy link

tomalec commented Jul 18, 2012

I'm not sure if I'm using group correctly, but

I try to get array of errors from my observableArray elements
http://jsfiddle.net/tomalec/DWACW/
The problem is that if you enter both invalid values, null appears in ko.validation.group(self.rows, { deep: true, observable: true });

I found that null comes from self.rows.isValid(), but I didn't set any validator on observableArray itself.
If it is cascading effect, then why it doesn't appear in case on one invalid field?

Is there a way to get array without that effect? As I would say that array itself is fine for me, as it have proper length, etc.

@tomalec
Copy link
Author

tomalec commented Aug 1, 2012

Same problem appears even in sipler case with required rule
http://jsfiddle.net/tomalec/RWza9/
and there is even bigger one.

When I have two fileds, empty by default, that requires value, errors count is equal to 2 (as desired),
but after I have filled both of them, the error count is still 1 ([null]).

@stlk
Copy link

stlk commented Sep 1, 2012

I don't know if this behavior is desired, but I found a solution. To force validation.group to behave correctly you need to call observable instead of just passing it.

Using previous example:

ko.validation.group(self.rows()); // add parentheses 

@danjohnso
Copy link

I figured this out for anyone that comes across this. if your group is an observableArray, you need to just pass the unwrapped array as the group.

My app uses a validation function because I have groups attached to Tab objects, so I just check if the group coming in is an observable array and then call the observable in that scenario.

var TabValidation = function (tab) {
if (tab.IsValidatable) {
var group = tab.ValidationGroup;

            if (ko.isObservable(tab.ValidationGroup) && Object.prototype.toString.call(tab.ValidationGroup()) === '[object Array]') {
                group = tab.ValidationGroup();
            }

            var errors = ko.validation.group(group, { deep: true });
            tab.Errors(errors().length);
            errors.showAllMessages();
        }
    };

@crissdev crissdev added this to the v2.0 milestone Dec 24, 2014
@crissdev crissdev self-assigned this Dec 24, 2014
crissdev added a commit that referenced this issue Dec 24, 2014
@crissdev
Copy link
Member

The real problem is in collectErrors - this function is executed from a computed which creates dependencies on error and isValid properties. When any of the observables in the group is validated, validateObservable invokes setError or clearError thus triggering a change to error property then to isValid. This is why the computed returned by ko.validation.group is notified many times and with intermediary states.
The solution to this is to use peek for error property to prevent a dependency to be created - this will not break the existing functionality because isValid is set whenever error is set through setError or clearError.

    function collectErrors(array) {
        var errors = [];
        ko.utils.arrayForEach(array, function (observable) {
            if (!observable.isValid()) {
                // Use peek to prevent a dependency to 'error' property because it
                // changes before 'isValid' does. (Issue #99)
                errors.push(observable.error.peek());
            }
        });
        return errors;
    }

@crissdev
Copy link
Member

Working example http://jsfiddle.net/tnj6u5fs/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants