Skip to content

Commit

Permalink
fix(json-schema): support oneOf with array mixed type
Browse files Browse the repository at this point in the history
fix #3769, fix #3785
  • Loading branch information
aitboudad committed Sep 28, 2023
1 parent a387a6c commit bcf930b
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 11 deletions.
28 changes: 28 additions & 0 deletions src/core/json-schema/src/formly-json-schema.service.spec.ts
Expand Up @@ -1300,6 +1300,34 @@ describe('Service: FormlyJsonschema', () => {
expect(foo2Field.hide).toBeFalse();
});

it('should support oneOf with array mixed type', () => {
const { field, setInputs } = renderComponent({

Check warning on line 1304 in src/core/json-schema/src/formly-json-schema.service.spec.ts

View workflow job for this annotation

GitHub Actions / build

'setInputs' is assigned a value but never used. Allowed unused vars must match /^_/u
model: [{ foo: [2] }],
schema: {
type: 'array',
items: {
oneOf: [
{ type: 'string' },
{
type: 'array',
items: { type: 'string' },
},
],
},
},
});

const [
,
{
fieldGroup: [foo1Field, foo2Field],
},
] = field.fieldGroup[0].fieldGroup[0].fieldGroup;

expect(foo1Field.hide).toBeTrue();
expect(foo2Field.hide).toBeFalse();
});

it('should support oneOf for a non-object type', () => {
const { field } = renderComponent({
model: { foo: 2 },
Expand Down
26 changes: 19 additions & 7 deletions src/core/json-schema/src/formly-json-schema.service.ts
Expand Up @@ -394,30 +394,42 @@ export class FormlyJsonschema {
// TODO: remove isEnum check once adding an option to skip extension
if (!this.isEnum(schema)) {
field.fieldArray = (root: FormlyFieldConfig) => {
if (!Array.isArray(schema.items)) {
const items = schema.items as JSONSchema7 | JSONSchema7[];
if (!Array.isArray(items)) {
if (!items) {
return {};
}

const isMultiSchema = items.oneOf || items.anyOf;

// When items is a single schema, the additionalItems keyword is meaningless, and it should not be used.
const f = schema.items ? this._toFieldConfig(<JSONSchema7>schema.items, options) : {};
if (f.props) {
f.props.required = true;
const f = this._toFieldConfig(
items,
isMultiSchema ? { ...options, key: `${root.fieldGroup.length}` } : options,
);

if (isMultiSchema && !f.key) {
f.key = null;
}

f.props.required = true;

return f;
}

const length = root.fieldGroup ? root.fieldGroup.length : 0;
const itemSchema = schema.items[length] ? schema.items[length] : schema.additionalItems;
const itemSchema = items[length] ? items[length] : schema.additionalItems;
const f = itemSchema ? this._toFieldConfig(<JSONSchema7>itemSchema, options) : {};
if (f.props) {
f.props.required = true;
}
if (schema.items[length]) {
if (items[length]) {
f.props.removable = false;
}

return f;
};
}

break;
}
}
Expand Down
10 changes: 6 additions & 4 deletions src/core/src/lib/templates/field-array.type.ts
Expand Up @@ -32,10 +32,11 @@ export abstract class FieldArrayType<F extends FormlyFieldConfig = FieldArrayTyp
}

for (let i = field.fieldGroup.length; i < length; i++) {
const f = {
...clone(typeof field.fieldArray === 'function' ? field.fieldArray(field) : field.fieldArray),
key: `${i}`,
};
const f = { ...clone(typeof field.fieldArray === 'function' ? field.fieldArray(field) : field.fieldArray) };
if (f.key !== null) {
f.key = `${i}`;
}

field.fieldGroup.push(f);
}
}
Expand Down Expand Up @@ -65,6 +66,7 @@ export abstract class FieldArrayType<F extends FormlyFieldConfig = FieldArrayTyp
private _build() {
const fields = (this.field as FormlyFieldConfigCache).formControl._fields ?? [this.field];
fields.forEach((f) => this.options.build(f));
this.field.options.detectChanges(this.field);
this.options.fieldChanges.next({
field: this.field,
value: getFieldValue(this.field),
Expand Down

0 comments on commit bcf930b

Please sign in to comment.