# Custom renderer for oneOf - inside array items \[react\]

**URL:** <https://jsonforms.discourse.group/t/custom-renderer-for-oneof-inside-array-items-react/2473>\
**Category:** General\
**Created:** [November 27, 2024, 8:35pm UTC](https://jsonforms.discourse.group/t/custom-renderer-for-oneof-inside-array-items-react/2473 "2024-11-27T20:35:00Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![cihad](https://yyz2.discourse-cdn.com/free1/user_avatar/jsonforms.discourse.group/cihad/32/1166_2.png) [@cihad](https://jsonforms.discourse.group/u/cihad)\
**Post date:** [November 27, 2024, 8:35pm UTC](https://jsonforms.discourse.group/t/custom-renderer-for-oneof-inside-array-items-react/2473/1 "2024-11-27T20:35:00Z")

</div>

I have:

```javascript
const schema = {
  type: "object",
  title: "Auth.js Settings",
  properties: {
    providers: {
      type: "array",
      title: "Providers",
      items: {
        type: "object",
        oneOf: [
          {
            properties: {
              type: { const: "google" },
              clientId: { type: "string" },
              clientSecret: { type: "string" },
            },
            required: ["type", "clientId", "clientSecret"],
            additionalProperties: false,
          },
          {
            properties: {
              type: { const: "github" },
              clientId: { type: "string" },
              clientSecret: { type: "string" },
            },
            required: ["type", "clientId", "clientSecret"],
            additionalProperties: false,
          },
          {
            properties: {
              type: { const: "credentials" },
              authorize: { type: "string", format: "uri" },
            },
            required: ["type", "authorize"],
            additionalProperties: false,
          },
        ],
      },
    },
  },
};

```

Normally oneOf, material appears as tab. But I want to show it as select instead of tabs with a custom renderer with an option. How can I write a tester for this? And how can the UI Schema be?

```js
const uiSchema = {
  type: "VerticalLayout",
  elements: [
    {
      type: "Control",
      scope: "#/properties/providers",
      options: { format: "select" },
    },
  ],
};

```

I did it this way but the format option here is valid for array. I can’t get this option in tester. Is there a ui schema for Items? Are there any examples?

---

<div class="post-metadata">

**Author:** ![cihad](https://yyz2.discourse-cdn.com/free1/user_avatar/jsonforms.discourse.group/cihad/32/1166_2.png) [@cihad](https://jsonforms.discourse.group/u/cihad)\
**Post date:** [November 28, 2024, 12:10am UTC](https://jsonforms.discourse.group/t/custom-renderer-for-oneof-inside-array-items-react/2473/2 "2024-11-28T00:10:16Z")

</div>

After much effort:

```js
export const uiSchema = {
  type: "VerticalLayout",
  elements: [
    {
      type: "Control",
      scope: "#/properties/providers",
      options: {
        detail: {
          type: "Control",
          scope: "#",
          options: { format: "x:select" },
        },
      },
    },
  ],
};

```

and the tester:

```js
export const selectOneOfControlTester: RankedTester = rankWith(
  4,
  and(isOneOfControl, optionIs("format", "x:select"))
);

```

but there is still a problem. const values are not included in the data. I think this is because of [createDefaultValue](https://github.com/eclipsesource/jsonforms/blob/fcef896c8927269d3f3ed609a7255651085b193d/packages/material-renderers/src/complex/MaterialOneOfRenderer.tsx#L88) and [extractDefaults](https://github.com/eclipsesource/jsonforms/blob/fcef896c8927269d3f3ed609a7255651085b193d/packages/core/src/mappers/renderer.ts#L209).

---

<div class="post-metadata">

**Author:** ![lucas-koehler](https://yyz2.discourse-cdn.com/free1/user_avatar/jsonforms.discourse.group/lucas-koehler/32/336_2.png) [@lucas-koehler](https://jsonforms.discourse.group/u/lucas-koehler)\
**Post date:** [November 29, 2024, 9:12am UTC](https://jsonforms.discourse.group/t/custom-renderer-for-oneof-inside-array-items-react/2473/3 "2024-11-29T09:12:40Z")

</div>

Hi @cihad ,  
Looking at the code of `createDefaultValue` and `extractDefaults`, I think you could get the `const` values to be initialized by also defining their value via a `default` property. See here in the code: [https://github.com/eclipsesource/jsonforms/blob/fcef896c8927269d3f3ed609a7255651085b193d/packages/core/src/mappers/renderer.ts#L174-L176](https://github.com/eclipsesource/jsonforms/blob/fcef896c8927269d3f3ed609a7255651085b193d/packages/core/src/mappers/renderer.ts#L174-L176)

ALthough this might not strictly be necessary, I think it makes sense to specify the `type` also for the `const` properties because JSON Forms uses the `type` property quite often.

For instance, do something like this:

```json
type: { const: "github", "default": "github", "type": "string" },

```

Arguably it could make sense to extend `createDefaultValue` to set the `const` value automatically. If you like you can open an issue for that.

Best regards,  
Lucas

---

<div class="post-metadata">

**Author:** ![cihad](https://yyz2.discourse-cdn.com/free1/user_avatar/jsonforms.discourse.group/cihad/32/1166_2.png) [@cihad](https://jsonforms.discourse.group/u/cihad)\
**Post date:** [November 29, 2024, 10:53am UTC](https://jsonforms.discourse.group/t/custom-renderer-for-oneof-inside-array-items-react/2473/4 "2024-11-29T10:53:04Z")

</div>

I will open an issue for that. I’m not sure if it should be a feature request or a bug report.

---

<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:** [November 29, 2024, 11:24am UTC](https://jsonforms.discourse.group/t/custom-renderer-for-oneof-inside-array-items-react/2473/5 "2024-11-29T11:24:59Z")

</div>

> [@lucas-koehler](#):
>
> Arguably it could make sense to extend `createDefaultValue` to set the `const` value automatically. If you like you can open an issue for that.

Personally I would prefer to not do that. If we always generate `const` values, we remove the option to _not_ generate them.

I don’t see a strong reason to treat `const` values as a special case here. If they should be auto-generated, a `default` should be specified just like with all other values.

---

<div class="post-metadata">

**Author:** ![lucas-koehler](https://yyz2.discourse-cdn.com/free1/user_avatar/jsonforms.discourse.group/lucas-koehler/32/336_2.png) [@lucas-koehler](https://jsonforms.discourse.group/u/lucas-koehler)\
**Post date:** [November 29, 2024, 11:48am UTC](https://jsonforms.discourse.group/t/custom-renderer-for-oneof-inside-array-items-react/2473/6 "2024-11-29T11:48:34Z")

</div>

That makes sense. I haven’t considered that but I agree that it is beneficial to leave the option open to not generate these const values.

---

<div class="post-metadata">

**Author:** ![cihad](https://yyz2.discourse-cdn.com/free1/user_avatar/jsonforms.discourse.group/cihad/32/1166_2.png) [@cihad](https://jsonforms.discourse.group/u/cihad)\
**Post date:** [November 30, 2024, 12:14am UTC](https://jsonforms.discourse.group/t/custom-renderer-for-oneof-inside-array-items-react/2473/7 "2024-11-30T00:14:39Z")

</div>

It seems strange that values like `""` for string, `0` for number, `false` for boolean, `null` for null, etc., which are not given a default value, are generated, but `const`, which has a stronger expression than these (because it indicates exactly what it should be), is not given a default value.

Can you give an example of what are the negative situations that this would cause?

Actually, I think what I want to talk about and what @sdirix is talking about are different things. Mine is about oneOf tab transitions and filling new values in oneOf controller component with `createDefaultValue`. I am sure @sdrix is talking about another situation. This function is already used in 3 places:

1st when adding a new item to the array,  
2nd in oneOf tab transitions,  
3rd in anyOf tab transitions if the data types are different.

---

<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:** [December 2, 2024, 11:54am UTC](https://jsonforms.discourse.group/t/custom-renderer-for-oneof-inside-array-items-react/2473/8 "2024-12-02T11:54:41Z")

</div>

@cihad, you’re right I was mainly thinking about use case 1 (adding new item to array) in the object case in which we check the `default` of all properties.

I agree, in case we’re not in the object case and need to create a value from somewhere, then there is no reason to not be a bit smarter and use the `const` if the property has it.

So I’m fine with adding that logic to the `createDefaultValue` [here](https://github.com/eclipsesource/jsonforms/blob/fcef896c8927269d3f3ed609a7255651085b193d/packages/core/src/mappers/renderer.ts#L169) 👍
