0

A few weeks ago, I've asked how to save Many-To-Many associations with breeze.

Ward Bell came up with this nice solution: breeze: many-to-many issues when saving

I've implemented his solution and it works really well. One issue I've come up with recently though, is how to track errors ?

Taking Ward's example, we manipulate UserRoleVm instances. Therefore validationErrorsChanged will not be triggered for this property.

How could I use breeze to raise an error if say, the parent entity does not have at least one UserRoleVm entity in its collection ?

Community
  • 1
  • 1
Sam
  • 13,934
  • 26
  • 108
  • 194
  • reading the doc and see if I'd find the solution in there :) But with no luck. Adding the vm to the metadata does not make sense, but on the other hand I don't see any other ways for breeze to be able to validate and raise errors on this property. – Sam Feb 24 '14 at 15:21

2 Answers2

0

The UserRoleVm is a regular JavaScript object. It is not a Breeze entity and so does not participate in the Breeze validation support. There is no obvious way to make it do so (at least not obvious to me). Almost anything I can dream up would be more complicated than writing traditional, view-based validation.

What kind of validation do you need? In the example that I put together, the user can only add and remove roles (the equivalent of super powers). There is no way the user can touch any value of the corresponding mapping entity (which may not even exist yet).

When I turn my imagination loose, I speculate about the rules governing how many roles the user can have or whether certain combinations of rule are allowed ... or disallowed. Is that what you mean?

If I had such rules, I'd build validation logic into the outer ViewVM (not the UserRoleVMs) ... the VM that supervises the user's actions. This logic would be quite apart from the Breeze validation logic that you register in metadata ... the validation rules implemented by Breeze inside each entity's EntityAspect.

Ultimately, I would have Breeze validations too ... probably entity validations on the parent User entity type ... so that I could guard against an actual attempt to save an invalid UserRole combination.

But such Breeze validation rules wouldn't kick in until you tried to save. While the user is working with "item VMs" (the UserRoleVms), the validation rules would be defined and implemented separately by the ViewVM in good old vanilla JavaScript.

Such is my thinking at the moment.

Ward
  • 17,793
  • 4
  • 37
  • 53
  • The validation I need is that the application user should not be able to save a new user without assigning at least one role. In other words there must be at least one UserRole item in the many-2-many association. If the user attempts saving, there should be a validation error and a * would show next to the UserRole user-control. I understand that the VM object is not a Breeze entity, but since I've implemented all my validation mechanism around Breeze 's validationErrorsChanged property, I was hoping there'd be a way for doing this kind of thing. I think we need Breeze to support m-2-m :) – Sam Feb 25 '14 at 08:32
  • You can write such a validation rule for the user entity and include a modified user in the save. Then the save logic will intercept it before the save goes to the server and you can reflect that back to the UI. I still think I'd have a warning on the View indicating the need for at least one role. You could disable save until they had at least one. – Ward Feb 25 '14 at 19:14
  • Btw, forcing a mod to the `User` when changing dependent members like `UserRoles`) is a good technique for handling concurrency; I like to do that at the "Aggregate Root" rather than do checks at member entity level. But I digress. As for "m-2-m", you are not alone. I hate it personally but we'll probably do it anyway. – Ward Feb 25 '14 at 19:17
  • Ward, see my reply below. – Sam Feb 26 '14 at 12:52
0

Following Ward's advice, I have:

-added the following code for forcing User entity's state to be modified whenever a UserRoleVM is added or removed:

  $scope.user.entityAspect.setModified();

-added a custom validator for validating the UserRoles collection on the User entity:

function notEmptyCollectionValidator() {
        var name = "notEmptyCollectionValidator";

        var validator = new breeze.Validator(name, function (value) {
            if (!value || value.length === 0) {
                return false;
            } else {
                return true;
            }
        });

        return validator;
    }

 breeze.Validator.registerFactory(notEmptyCollectionValidator, 'notEmptyCollectionValidator');


 var entityType = metadataStore.getEntityType('User');
 entityType.getProperty('userRoles').validators.push(breeze.config.functionRegistry['Validator.notEmptyCollectionValidator']());

Now when I hit the save button, the validation occurs on the userRoles collection. If no userRole was selected, I get a validation error and I show a * next to the control in th UI.

Obviously, that does not work for OnChange validation. I don't know yet how I'm going to achieve that.

Sam
  • 13,934
  • 26
  • 108
  • 194