1
votes

I have a client side model generated by Breeze/OData and I used the code in this post to connect it to Knockout validation.

It works great for validating individual fields through the isValid() method. However, whenever I try to use ko.validation.group against a Breeze Entity (assume that the knockout validation is configured with {deep: true}), either calling showAllMessages, length or any other method that performs a tree traversal over the object graph, results in an infinite recursion exception at runtime (see knockout.validation.js@231-271). Depending on the browser can be "Out of stack space" (IE) or "Too much recursion" (Firefox).

I think the root cause of the error is that the algorithm inside Knockout Validation does not keep track of the previously visited nodes. All Breeze Entities contain an entityAspect property and the code inside knockout.validation visits all the properties and all its children using depth first, but without remembering the nodes already visited. And because entityAspect contains a reference back to its containing entity, it results in a stack overflow.

validate(entity) // Initial call
    => validate(entity.entityAspect) // Validate the first property of the root
    => validate(entity.entityAspect.entity) // Validate the first property of the child, which points back to the root!

So after all this, the question is: do you know any work around to avoid this behavior?

For now, I think I'm just going to use a dirty cheap hack inside knockout.validation to prevent stepping into an entityAspect property, but I'm sure there should be a better way.

faced a similar problem yesterday. also using a dirty dirty workaround (validation group for every navigation property, since i only need two). really not happy with that, looking forward for some answers :)chris vietor
I do not know an easy way around this. Circular references are common in real world entity models (e.g., Customers have Orders and those orders refer back to their parent customers).Ward
You might consider my answer to this other SO question in which I suggest writing custom validations to do the hard stuff.Ward