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

Getting observables associated with errors? #449

Closed
grofit opened this issue Aug 27, 2014 · 9 comments
Closed

Getting observables associated with errors? #449

grofit opened this issue Aug 27, 2014 · 9 comments
Milestone

Comments

@grofit
Copy link
Contributor

grofit commented Aug 27, 2014

I have noticed a few other issues related to this such as:

#298

However I cannot find any documentation around if this sort of thing made it into the main branch and if so how to best use it.

My scenario is in nodejs on a webservice I get sent json which I convert into a model with validation rules applied then via the group method I get all the errors, then throw them back as errors if something failed validation. However all I get is the errors, and I can manually go change the code, however every time a release happens and it pulls the latest version of knockout.validation from npm I will lose it :(

So is there any way to get the errors and the observable name or property it is linked to?

(If this functionality is already existing it could just be that the npm package for knockout validation just needs updating)

@brettmorien
Copy link
Contributor

Bump.

We have a more limited case for this need, wanting only a collection of validation errors which have been evaluated/ shown. It can be accomplished by adding a new method, like:

result.shownMessages = ko.computed(function() {
    // ensure we have latest changes
    result();

    return koUtils.arrayMap(koUtils.arrayFilter(context.validatables, function (observable) {
        return utils.isValidatable(observable) && !observable.isValid() && observable.isModified();
    }), function(item) { return item.error.peek(); });
});

However, the comment above (plus previous discussions) would handle this case and more.

@crissdev
Copy link
Member

crissdev commented Jan 7, 2015

Thanks @askheaves

There are more use cases which require access to context.validatables and this will be addressed in future versions of the library. I'm thinking to somthing similar to the solution presented in this comment.

@brettmorien
Copy link
Contributor

If I wrote this up, would you accept it as a pull request? It should be something pretty simple, like this:

result.filter = function(predicate) {
    predicate = predicate || function () { return true; };
    // ensure we have latest changes
    result();

    return koUtils.arrayFilter(context.validatables, predicate);
}

If you worry about the raw observables getting mucked with, an alternative would be to project the validatables into their own collection, something like:

result.validatables = ko.computed(function() {
    // ensure we have latest changes
    result();

    return koUtils.arrayMap(context.validatables, function(observable) {
        return {
            isValid: observable.isValid(),
            isModified: observable.isModified(),
            value: observable(),
            error: observable.error.peek()
        };
    });
});

@crissdev
Copy link
Member

crissdev commented Jan 8, 2015

Looking at the second example it makes me think the first option is much better. I would be fine with adding this method but I would also like to have the find method included because it will simplify things like isValid or isModified because the object passed to ko.validation.group is no longer decorated with methods like isValid - see #465.
What do you think?

@brettmorien
Copy link
Contributor

I'm ok with doing a find and filter and submitting that.

The main advantage to option 2 (return a projected array) is that all array functions are immediately available, and you don't expose any underlying structure. The downside is a new object schema which I've put very little thought into so far. With option 1 we may be playing catch up on needed collection functions, but we can get a lot of mileage out of find, filter and map (and maybe forEach).

I'll rough up these functions and tests today and get a pull request in your direction.

@crissdev
Copy link
Member

crissdev commented Jan 8, 2015

To be honest I wish it could be a better way to do all this. One of the problems of option 2 is that the computed will be eagerly evaluated and if observable is a computed with a defered evaluation then 💥 we have a bug.
The reason I prefer the first option - even though we introduce 2 functions instead of a computed, is because it gives you freedom to do whatever you like and still allow us to make changes in the future to the underlying validatables structure.
Although option 1 might be difficult to use than option 2, it doesn't enforce you to any object schema and has no side effects. It should also make people happy having access to the validatables items.
Future versions of the library will have better support over grouping, displaying messages, classes etc. and probably this feature will be deprecated.

@brettmorien
Copy link
Contributor

I'm good with all that, and the eager evaluation is a good point. I have the 4 methods coded up now (find, filter, map, forEach), and am currently writing up the unit tests. I should have something for you today.

@crissdev
Copy link
Member

crissdev commented Jan 8, 2015

👍

@brettmorien
Copy link
Contributor

Awesome. Thanks!

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

No branches or pull requests

3 participants