Conditional Required is not working on Angular 17

Hello there!

i m trying to reproduce the logic on conditional required fields based on other fields values.

I have implemented a custom angular component that is passed on the renderers.

My Schema is the following:

schema.json

{
  "type": "object",
  "properties": {
    "fooCarbonToggle": { "type": "boolean" },
    "barCarbonToggle": { "type": "boolean" },
    "bazCarbonToggle": { "type": "boolean" }
  },
  "required": ["bazCarbonToggle"],
  "if": {
    "properties": {
      "fooCarbonToggle": { "const":  true }
    }
  },
  "then": {
    "required": ["barCarbonToggle"]
  }
}

UiSchema.json

{
  "type": "VerticalLayout",
  "elements": [
    {
      "type": "Control",
      "scope": "#/properties/fooCarbonToggle",
      "label": "Foo "
    },
    {
      "type": "Control",
      "scope": "#/properties/barCarbonToggle",
      "label": "Bar"
    },
    {
      "type": "Control",
      "scope": "#/properties/bazCarbonToggle",
      "label": "Baz"
    }
  ]
}

The initial state is like that:
image

and even after i toggle the values to true, the field is still as not required.

The logs on the console tab, comes from my component that extends JsonFormsControl which looks like this:

export class CarbonToggleComponent extends JsonFormsControl {

  private initialStep = true;
  private propertyName: string = '';
  private readonly PROPERTY_NAME = 'propertyName';

  constructor(service: JsonFormsAngularService) {
    super(service);
  }

  override ngOnInit() {
    super.ngOnInit();
  }

  override onChange(event: boolean) {
    const userData = this.jsonFormsService.getState().jsonforms.core?.data;

    const dataToUpdate =
      {...userData, [this.propertyName]: event}

    this.jsonFormsService.setData(dataToUpdate)

  }

  override mapAdditionalProps(props: StatePropsOfControl) {
    console.log(props.label, 'is required', props.required, )

    if (this.initialStep) {

      this.propertyName = props.path;


      this.initialStep = false;
    }
  }

}

the versions i use in my 17.3.0 Angular project in the package.json is:

"@jsonforms/angular": "^3.3.0",
"@jsonforms/angular-material": "^3.3.0",
"@jsonforms/core": "^3.3.0",

i would really appreciate any help

Hi @kasar,

looking at your JSON Schema, I think it has a bug: When the if condition is true, you effectively have two required properties in your schema. Can you try rectifying that. E.g. like this:

{
  "type": "object",
  "properties": {
    "fooCarbonToggle": { "type": "boolean" },
    "barCarbonToggle": { "type": "boolean" },
    "bazCarbonToggle": { "type": "boolean" }
  },
  "if": {
    "properties": {
      "fooCarbonToggle": { "const":  true }
    }
  },
  "then": {
    "required": ["bazCarbonToggle", "barCarbonToggle"]
  },
  "else": {
    "required": ["bazCarbonToggle"]
  }
}

Hello @lucas-koehler,

i updated the schema.json to the one you proposed but still there is no “update” on the required fields:

Also @lucas-koehler , is there any possibility that the validation is not getting updated because of the way i m overriding the onChange or mapAdditionalProps methods?

Hi @kasar
I could imagine your override of onChange could cause validation not to be triggered.
If you have a look at the onChange code in JsonFormsAbstractControl, you can see the data there is updated like this:

onChange(ev: any) {
    this.jsonFormsService.updateCore(
      Actions.update(this.propsPath, () => this.getEventValue(ev))
    );
    this.triggerValidation();
  }

Here, an action is used and then the validation triggered. As you do not seem to do anything special in your override of onChange, you could try not overriding it and see how it goes with the default implementation.

Overriding mapAdditionalProps should not be a problem because it does nothing by default anyway and is meant to be overridden.

I tried removing the onChange as well but no luck. The fields are still not required.|

I m sharing a live reproducible devBox in order to check if there is something else wrong.

https://codesandbox.io/p/devbox/ng-17-jsonforms-r2wsn2

Please have a look on it and feel free to edit it, if needed

Hi @kasar,
I had another look into our open issues and found out that the if/then/else for required is not supported. See this issue Render conditional properties defined in `if` · Issue #2262 · eclipsesource/jsonforms · GitHub.
The issue is labeled for react and material but should also apply to angular material because the react material renderers tend to support the most features.

Sorry for noticing earlier!

Best regards,
Lucas

Hello @lucas-koehler ,

do you intend to include this feature in the future?

If yes, is there any specific delivery date?

Thanks,
Kostas

Hi @kasar ,
I actually linked the wrong issue. The relevant one is this one: Required property is not set if field is conditionally required · Issue #1390 · eclipsesource/jsonforms · GitHub

However, that doesn’t change much. Currently, there is no plan to implement this ourselves. Hence, it is in the backlog milestone. We do accept contributions for these issues though.

Best regards,
Lucas

Thanks for the immediate response @lucas-koehler .

Is it possible to provide me the ticket and/or any reference/example/guidance of how it could be implemented so i could check if it would be possible for me to implement it and open a PR to json-forms so i contribute as well?

Best regards,
Kostas

Hi @kasar,

We do not have an approach how the if/then/else would be implemented for all cases unfortunately. Also see this comment: Required property is not set if field is conditionally required · Issue #1390 · eclipsesource/jsonforms · GitHub

I had another look and discovered there is already a open (albeit incomplete) PR for dynamically evaluation the required: Fix conditionally required property not applying by gatanasov-asteasolutions · Pull Request #2228 · eclipsesource/jsonforms · GitHub
I noticed that there were some concerns because of the dynamic evaluation. I took that with me to discuss with the team if and how this could be supported in a feasible manner that also does not impact performance too much.

Best regards,
Lucas