guillotinaweb / ngx-schema-form

HTML form generation based on JSON Schema
MIT License
485 stars 174 forks source link

Proposal to add nullable union like ["integer", "null"] #397

Closed iperevozchikov closed 2 years ago

iperevozchikov commented 3 years ago

Hello and I'm again.

Problem brief: I have a response from backend server something like this:

{
    type: 'object',
    properties: {
        issuePriority: {
            type: "integer",
            oneOf: [
                {
                    description: '',
                    enum: [null],
                },
                {
                    description: 'Minor',
                    enum: [1],
                },
                {
                    description: 'Major',
                    enum: [2],
                }
            ]
        }
    }
}

And validation showed me error message that "Data does not match any schemas from 'oneOf'". After that I started to researching and found that in JsonSchema v6 may be using union types like ["integer", "null"]. After that I modified schema above and tested via z-schema - the error was disappeared. Inspired I injected schema code above to my project but recieve error that union is not supported.

Proposal: Extend FormPropertyFactory with supporting union like this [<number|boolean|string|integer>, "null"]:

createProperty(schema: ISchema, parent: PropertyGroup = null, propertyId?: string): FormProperty {
  ...

  // Pseudocode
  let type;
  if (schema.type is union && union is nullable) {
    type = extractPrimitiveType(schema.type);
  } else {
    throw new Error('');
  }

  if (PROPERTY_TYPE_MAPPING[type]) {
    if (type === 'object' || type === 'array') {
      newProperty = PROPERTY_TYPE_MAPPING[schema.type](this.schemaValidatorFactory, this.validatorRegistry, this.expressionCompilerFactory, schema, parent, path, this, this.logger);
    } else {   
      newProperty = PROPERTY_TYPE_MAPPING[type](
      this.schemaValidatorFactory, this.validatorRegistry, this.expressionCompilerFactory, schema, parent, path, this.logger);
    }
  } else {
    throw new TypeError(`Undefined type ${schema.type} (existing: ${Object.keys(PROPERTY_TYPE_MAPPING)})`);
  }

  ...
}

What do you think about solution? If for owners it's ok, I'll prepare PR later

ebrehault commented 3 years ago

Hi Igor, It sounds good to me :)

iperevozchikov commented 3 years ago

@ebrehault https://github.com/guillotinaweb/ngx-schema-form/pull/398