# Altering schema during dispatching

**URL:** <https://jsonforms.discourse.group/t/altering-schema-during-dispatching/2172>\
**Category:** General\
**Created:** [May 31, 2024, 5:27pm UTC](https://jsonforms.discourse.group/t/altering-schema-during-dispatching/2172 "2024-05-31T17:27:09Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Jojain](https://yyz2.discourse-cdn.com/free1/user_avatar/jsonforms.discourse.group/jojain/32/967_2.png) [@Jojain](https://jsonforms.discourse.group/u/Jojain)\
**Post date:** [May 31, 2024, 5:27pm UTC](https://jsonforms.discourse.group/t/altering-schema-during-dispatching/2172/1 "2024-05-31T17:27:09Z")

</div>

Hello,  
I’m creating a dynamic UI from generated JSON Schema coming from pydantic Python code.  
Due to how pydantic works when I have an optional field it create this schema :

```auto
"name": {
    "anyOf": [
        {
            "type": "string"
        },
        {
            "type": "null"
        }
    ],
    "default": null,
    "title": "Name"
}
```

Out of the box JsonForms renders this kind of schema with a tabbed control which is not what I want. My plan is to create an _OptionalRender_ that will alter the subschema to remove the “anyOf”/“null” part and keep only the non null object.

To do so I have created the following component :

```auto
function _OptionalRenderer(props: RendererProps) {
    let editedSchema = { ...props.schema } as JsonSchema;

    const nonNullType = editedSchema.anyOf?.find(obj => obj.type !== "null") as { type: string };
    delete editedSchema.anyOf;
    editedSchema = { ...editedSchema, ...nonNullType };

    return <JsonFormsDispatch {...props} schema={editedSchema} />;
}

export const OptionalRenderer = withJsonFormsControlProps(_OptionalRenderer);
```

With its tester :

```auto
const isOptional: Tester = (uischema, schema, context) => {
    if (!isAnyOfControl(uischema, schema, context))
        return false;
    const controlUISchmea = uischema as ControlElement;
    const resolved = resolveSchema(schema, controlUISchmea.scope, context.rootSchema);
    if (!resolved?.anyOf || resolved.anyOf.length !== 2)
        return false;
    return resolved.anyOf.some(obj => obj.type === "null");
}
const optionalFormTester = rankWith(4, isOptional);
const optionalRenderer = { tester: optionalFormTester, renderer: OptionalRenderer };
```

With this setup for the schema posted above its correctly rendering a unique TextControl as expected however, I get validation errors on the `onChange` callback of the `JsonForms` component.

Looking at the error :

```auto
{
  instancePath: "/name",
  schemaPath: "#/properties/name/anyOf/0/type",
  keyword: "type",
  params: {
    type: "string",
  },
  message: "must be string",
  schema: "string",
  parentSchema: {
    type: "string",
  },
  data: {
    name: "uu",
  },
}
```

I feel like the issue is because the data is an object with a name key rather than the plain text data. I don’t know why I get an object `name:"uu"` instead of just `uu`. I suspect that the issue comes from the schema alteration I’ve done but I can’t understand how to solve this issue.

If the solution I’ve found to alter the schema is a dead end I’m interested in other solution to solve my issue.

PS : I am looking for a general solution not a specific solution for this specific schema

Thanks !

---

<div class="post-metadata">

**Author:** ![sdirix](https://yyz2.discourse-cdn.com/free1/user_avatar/jsonforms.discourse.group/sdirix/32/1073_2.png) [@sdirix](https://jsonforms.discourse.group/u/sdirix)\
**Post date:** [June 4, 2024, 8:13pm UTC](https://jsonforms.discourse.group/t/altering-schema-during-dispatching/2172/2 "2024-06-04T20:13:01Z")

</div>

Hi @Jojain,

Interesting use case! The problem here is that the `withJsonFormsControlProps` is basically called twice on mostly the same set of parameters.

One of them is the `path` parameter. The data `path` is modified to `name` via the first `withJsonFormsControlProps` of your custom optional renderer. But then you dispatch again, so the text control renderer will again run `withJsonFormsControlProps`. In it it will detect that it renders a `name` field, so it will append `name` to the `path`, resulting in `name.name`. And this is why the data is modified like this.

You can fix this by NOT wrapping your custom control in `withJsonFormsControlProps`, slightly adapt the code (as your `schema` will be the parent one) and then dispatch as you do.

Note that creating a new `schema` with every render call will force all children to also rerender whenever the custom renderer rerenders. If you want to prevent this you should wrap it in a `useMemo`.
