Data in props for my custom oneOf renderer for vanilla set is undefined

I made my own oneOf renderer for objects for vanilla renderers in react. It renders but doesn’t show me what the current data is in the dropdown.

Any help would be very much appreciated
Here’s my schema and code:

{
  "properties": {
    "inputs": {
      "title": "inputs",
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "enabled": {
            "type": "boolean"
          },
          "negated": {
            "type": "boolean"
          },
          "safe": {
            "type": "boolean"
          },
          "connection": {
            "type": "object",
            "oneOf": [
              {
                "title": "TEMP",
                "type": "object",
                "const": {
                  "name": "TEMP",
                  "ioType": "input",
                  "safe": true
                }
              },
              {
                "title": "a1:i2",
                "type": "object",
                "const": {
                  "ioType": "input",
                  "name": "a1:i2",
                  "safe": true
                }
              },
              {
                "title": "a1:i5",
                "type": "object",
                "const": {
                  "ioType": "input",
                  "name": "a1:i5",
                  "safe": true
                }
              },
              {
                "title": "a1:i6",
                "type": "object",
                "const": {
                  "ioType": "input",
                  "name": "a1:i6",
                  "safe": true
                }
              },
              {
                "title": "a1:RLO: 0",
                "type": "object",
                "const": {
                  "ioType": "input",
                  "name": "a1:RLO: 0",
                  "safe": true
                }
              },
              {
                "title": "a1:RLO: 1",
                "type": "object",
                "const": {
                  "ioType": "input",
                  "name": "a1:RLO: 1",
                  "safe": true
                }
              }
            ]
          }
        }
      }
    }
  }
}

{
  "type": "Control",
  "scope": "#/properties/inputs",
  "options": {
    "detail": {
      "type": "HorizontalLayout",
      "elements": [
        {
          "type": "Control",
          "label": "",
          "scope": "#/properties/connection"
        }
      ]
    }
  }
}

import { ControlProps } from '@jsonforms/core/lib/mappers/renderer';
import { withJsonFormsOneOfEnumProps } from '@jsonforms/react';
import { withVanillaEnumCellProps } from '@jsonforms/vanilla-renderers';
import { CustomOneOfControl } from '../control/CustomOneOfControl';

export const CustomOneOfControlRenderer = (props: ControlProps) => {
    const { uischema, enabled, schema, data, visible, path, handleChange } = props;

    return (
        <CustomOneOfControl
            data={data}
            schema={schema}
            enabled={enabled}
            visible={visible}
            path={path}
            handleChange={handleChange}
            uischema={uischema}
        />
    );
};

export default withJsonFormsOneOfEnumProps(withVanillaEnumCellProps(CustomOneOfControlRenderer));
import { DispatchPropsOfControl, StatePropsOfRenderer } from '@jsonforms/core';
import React from 'react';

export const CustomOneOfControl = (props: StatePropsOfRenderer & DispatchPropsOfControl) => {
    const { schema, handleChange, path, data, enabled } = props;

    const handleSelectionChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
        const selectedSchema = schema.oneOf?.find(s => s.title === event.target.value);

        if (selectedSchema) {
            handleChange(path, selectedSchema.const);
        }
    };

    const optionsMap: JSX.Element[] = [];
    if (data) {
        optionsMap.push(<option key={data.name} label={data.name} value={data.name}></option>);
    }
    schema.oneOf?.forEach(option => optionsMap.push(<option key={option.title} label={option.title} value={option.title}></option>));
    return (
        <select onChange={handleSelectionChange} disabled={!enabled}>
            {optionsMap}
        </select>
    );
};

import { isOneOfControl, RankedTester, rankWith } from '@jsonforms/core';

export const CustomOneOfTester: RankedTester = rankWith(3, isOneOfControl);

Hi @nwoik,

I don’t see in your code where you actually set the value of the select? It seems that only the options are populated, not which one is selected.

Not directly related, but as you are already using withJsonFormsOneOfEnumProps there should be no need to manually construct the options list from the schema. Instead you should already have an options prop available.

My form works the first time it pops up, but every other time the value of data becomes undefined.

This is how I set the current value in my CustomOneOfControl. By placing it first in the options drop down.

if (data) {
        optionsMap.push(<option key={data.name} label={data.name} value={data.name}></option>);
}

image

And also the options suggestion you gave returns undefined as well