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.