Skip to content

Duplicate validation messages in primitive array renderer #1760

@jessevdp

Description

@jessevdp

Describe the bug

For primitive arrays, all validation messages are combined into 1, and the top level validation for the array (is required, min amount of items) seems to duplicate itself.

The error property seems to contain:

  • Validation messages for all items in the array
  • Validation messages for the top level array itself (min/max items validation, is required, etc.)

Screenshots

Validation messages for the individual items are also in the top level array renderer:

Screenshot 2021-05-28 at 11 27 35

Top level validation messages are duplicated:

Screenshot 2021-05-28 at 11 27 09

Expected behaviour

I would expect the error property of the Array control to only contain validation for the top level. The individual items in the array could render their own validation messages.

Additionally, I would expect the "is required" or "should NOT have fewer than X items" validation messages to not be duplicated like this.

To Reproduce

Array layout renderer:

export class ArrayLayoutRenderer extends JsonFormsArrayControl implements OnInit {

  private addItem: (path: string, value: any) => () => void;
  private removeItems: (path: string, toDelete: number[]) => () => void;

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

  remove(index: number): void {
    this.removeItems(this.propsPath, [index])();
  }
  add(): void {
    this.addItem(this.propsPath, createDefaultValue(this.scopedSchema))();
  }

  mapToProps(state: JsonFormsState): StatePropsOfArrayLayout {
    const props = mapStateToArrayLayoutProps(state, this.getOwnProps());
    return { ...props };
  }

  ngOnInit(): void {
    super.ngOnInit();

    const { addItem, removeItems } = mapDispatchToArrayControlProps(
      this.jsonFormsService.updateCore.bind(this.jsonFormsService)
    );
    this.addItem = addItem;
    this.removeItems = removeItems;
  }

  getProps(index: number): OwnPropsOfRenderer {
    return {
      schema: this.scopedSchema,
      path: Paths.compose(this.propsPath, `${index}`),
      uischema: controlWithoutLabel(`#`)
    };
  }

  trackByFn(index: number) {
    return index;
  }

}

Template file:

<label class="h6">{{ label }}</label>

<p class="text-hint mt-2 mb-1">{{ uischema['description'] }}</p>

<p class="caption-2 text-danger my-1">{{ error }}</p>

<button (click)="add()">Add</button>

<ng-container *ngFor="
    let item of [].constructor(data);
    let idx = index;
    trackBy: trackByFn;
    last as last
">
    <jsonforms-outlet [renderProps]="getProps(idx)"></jsonforms-outlet>
    <button (click)="remove(idx)">delete</button>
</ng-container>

Schema for this individual question:

{
  "list-question": {
    "type": "array",
    "minItems": 1,
    "items": {
      "type": "string",
      "minLength": 1
    }
  }
}

Used Setup (please complete the following information):

  • Framework: angular
  • RendererSet: custom, but based on Angular Material

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions