# Problem with custom renderer (reaching nested schema)

**URL:** <https://jsonforms.discourse.group/t/problem-with-custom-renderer-reaching-nested-schema/1537>\
**Category:** General\
**Created:** [June 15, 2023, 8:05pm UTC](https://jsonforms.discourse.group/t/problem-with-custom-renderer-reaching-nested-schema/1537 "2023-06-15T20:05:30Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ookami](https://avatars.discourse-cdn.com/v4/letter/o/e9c0ed/32.png) [@Ookami](https://jsonforms.discourse.group/u/Ookami)\
**Post date:** [June 15, 2023, 8:05pm UTC](https://jsonforms.discourse.group/t/problem-with-custom-renderer-reaching-nested-schema/1537/1 "2023-06-15T20:05:30Z")

</div>

Hello, I have a problem regarding creating custom renderer.

I have ui schema which includes this:

```auto
{
      "type": "Control",
      "scope": "#/properties/TradeSettingsOne",
    },
    {
      "type": "Control",
      "scope": "#/properties/TradeSettingsTwo",
    },

```

In Schema they are nested like this, first we pass ref:

```auto
"TradeSettingsOne": {
      "$ref": "#/definitions/commonTradeSettings"
    },

    "TradeSettingsTwo": {
      "$ref": "#/definitions/commonTradeSettings"
    },

```

And here we get a full object:

```auto
"commonTradeSettings": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "platform": {
            "type": "string"
          },
          "regions": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "region": {
                  "type": "string"
                },
                "ratioMin": {
                  "type": "number",
                  "description": "Min Ratio",
                  "minimum": 0.5,
                  "maximum": 1.1
                },
                "ratioMax": {
                  "type": "number",
                  "description": "Max Ratio",
                  "minimum": 0.5,
                  "maximum": 1.1
                }
              }
            }
          }
        }
      }
    },

```

In tester I need somehow to reach **ratioMin** and **ratioMax** properties, but I’ve already tried several functions such as **schemaMatches** or **schemaSubPathMatches** and even **isNumberControl** (as these properties have type number). But it doesn’t work. I think there is a lack in docs that I can’t see how I can reach nested schemas’ properties and also using refs. Could you guide me where to start digging? I really can’t understand:(

---

<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 19, 2023, 7:51am UTC](https://jsonforms.discourse.group/t/problem-with-custom-renderer-reaching-nested-schema/1537/2 "2023-06-19T07:51:01Z")

</div>

Hi @Ookami,

A tester looks like this: `(uischema, schema, context) => number`. The handed over parameters are the current ui schema element, the scoped schema (often just the root schema) and context where for example the root schema is contained. Using these parameters you are definitely able to resolve anything you like as you have all relevant information in your hand.

Helper functions like `schemaMatches` just do part of the job for you. For example `schemaMatches` looks at the `scope` in the uischema element and already resolves that for you. Normally we resolve until we no longer are hitting a `$ref`, so I would have expected that it works for your described case. It would be interesting why it fails: What does `schemaMatches` actually resolve to in your case? To reproduce it would also be helpful to paste the full schema, or a reproducible example and not only parts of it.

---

<div class="post-metadata">

**Author:** ![Ookami](https://avatars.discourse-cdn.com/v4/letter/o/e9c0ed/32.png) [@Ookami](https://jsonforms.discourse.group/u/Ookami)\
**Post date:** [June 19, 2023, 1:38pm UTC](https://jsonforms.discourse.group/t/problem-with-custom-renderer-reaching-nested-schema/1537/3 "2023-06-19T13:38:47Z")

</div>

Hello Stefan,

Thank you for your reply. Apologies for the confusion, let me then describe you what I do in details:

I have uiSchema:

{

```auto
  "type": "VerticalLayout",
  "elements": [
    {
      "type": "HorizontalLayout",
      "elements": [
        {
          "label": "Example Sellers",
          "type": "Control",
          "scope": "#/properties/exampleSellers",
          "options": {
            "readonly": true
          }
        },
        {
          "type": "Control",
          "scope": "#/properties/exampleSellers2",
          "options": {
            "readonly": true
          }
        }
      ]
    },
    {
      "type": "HorizontalLayout",
      "elements": [
        {
          "label": "Keys on Sellers",
          "type": "Control",
          "scope": "#/properties/keysAccountEnabledOnSellers",
          "options": {
            "toggle": true
          }
        },
        {
          "label": "Keys on Sellers2",
          "type": "Control",
          "scope": "#/properties/keysAccountEnabledOnSellers2",
          "options": {
            "toggle": true
          }
        }
      ]
    },
    {
      "type": "HorizontalLayout",
      "elements": [
        {
          "label": "Market on Sellers",
          "type": "Control",
          "scope": "#/properties/marketAccountEnabledOnSellers",
          "options": {
            "toggle": true
          }
        },
        {
          "label": "Market on Sellers2",
          "type": "Control",
          "scope": "#/properties/marketAccountEnabledOnSellers2",
          "options": {
            "toggle": true
          }
        }
      ]
    },
    {
      "type": "Control",
      "scope": "#/properties/sellersTradeSettings"
    },
    {
      "type": "Control",
      "scope": "#/properties/sellers2TradeSettings"
    },
    {
      "type": "Group",
      "label": "Sellers2 Commissions",
      "elements": [
        {
          "type": "Group",
          "label": "Market",
          "elements": [
            {
              "type": "HorizontalLayout",
              "elements": [
                {
                  "type": "Control",
                  "scope": "#/properties/seller2Commissions/properties/market/properties/percent"
                },
                {
                  "type": "Control",
                  "scope": "#/properties/seller2Commissions/properties/market/properties/fixed"
                }
              ]
            }
          ]
        },
        {
          "type": "Group",
          "label": "Keys",
          "elements": [
            {
              "type": "HorizontalLayout",
              "elements": [
                {
                  "type": "Control",
                  "scope": "#/properties/seller2Commissions/properties/keys/properties/percent"
                },
                {
                  "type": "Control",
                  "scope": "#/properties/seller2Commissions/properties/keys/properties/fixed"
                }
              ]
            }
          ]
        },
        {
          "type": "Control",
          "scope": "#/properties/seller2Commissions/properties/whenPriceLower"
        },
        {
          "type": "HorizontalLayout",
          "elements": [
            {
              "type": "Control",
              "scope": "#/properties/seller2Commissions/properties/lowValueProduct/properties/percent"
            },
            {
              "type": "Control",
              "scope": "#/properties/seller2Commissions/properties/lowValueProduct/properties/fixed"
            }
          ]
        },
        {
          "type": "Control",
          "scope": "#/properties/seller2Commissions/properties/platformCommission",
          "options": {
            "detail": {
              "type": "VerticalLayout",
              "elements": [
                {
                  "type": "Control",
                  "scope": "#/properties/platformNames",
                  "options": {
                    "readonly": true
                  },
                  "rule": {
                    "effect": "HIDE",
                    "condition": {}
                  }
                },
                {
                  "type": "Control",
                  "scope": "#/properties/platforms",
                  "options": {
                    "readonly": true
                  },
                  "rule": {
                    "effect": "HIDE",
                    "condition": {}
                  }
                },
                {
                  "type": "HorizontalLayout",
                  "elements": [
                    {
                      "type": "Control",
                      "scope": "#/properties/value/properties/percent"
                    },
                    {
                      "type": "Control",
                      "scope": "#/properties/value/properties/fixed"
                    }
                  ]
                }
              ]
            }
          }
        }
      ]
    },
    {
      "type": "Control",
      "scope": "#/properties/sellers3TradeSettings"
    },
    {
      "type": "Control",
      "scope": "#/properties/sellers3ProductTemplates",
      "options": {
        "detail": {
          "type": "VerticalLayout",
          "elements": [
            {
              "type": "Control",
              "scope": "#/properties/region"
            },
            {
              "type": "Control",
              "scope": "#/properties/description/properties/eur",
              "options": {
                "multi": true
              }
            },
            {
              "type": "Control",
              "scope": "#/properties/description/properties/us",
              "options": {
                "multi": true
              }
            },
            {
              "type": "Control",
              "scope": "#/properties/addInfo/properties/eur",
              "options": {
                "multi": true
              }
            },
            {
              "type": "Control",
              "scope": "#/properties/addInfo/properties/us",
              "options": {
                "multi": true
              }
            }
          ]
        }
      }
    }
  ]
}

```

And schema:

```auto
{
  "type": "object",
  "required": [
    "sellers2",
    "sellers",
    "sellersTradeSettings",
    "sellers2TradeSettings",
    "sellers3TradeSettings",
    "sellers2Commissions",
    "sellers3ProductTemplates"
  ],
  "properties": {
    "sellers2": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "sellers": {
      "description": "Example Sellers",
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "keysPriceMultiplier": {
      "type": "number",
      "minimum": 0,
      "maximum": 0.2,
      "default": 0.04
    },
    "keysAccountEnabledOnSellers": {
      "type": "boolean"
    },

    "keysAccountEnabledOnSellers2": {
      "type": "boolean"
    },
    "marketAccountEnabledOnSellers": {
      "type": "boolean"
    },

    "marketAccountEnabledOnSellers2": {
      "type": "boolean"
    },

    "sellersTradeSettings": {
      "$ref": "#/definitions/resellTradeSettings"
    },

    "sellers2TradeSettings": {
      "$ref": "#/definitions/resellTradeSettings"
    },

    "sellers3TradeSettings": {
      "$ref": "#/definitions/resellTradeSettings"
    },

    "sellers2Commissions": {
      "type": "object",
      "required": [
        "market",
        "keys",
        "whenPriceLower",
        "lowValueProduct",
        "platformCommission"
      ],
      "properties": {
        "market": {
          "$ref": "#/definitions/sellers2Commission"
        },
        "keys": {
          "$ref": "#/definitions/sellers2Commission"
        },
        "whenPriceLower": {
          "type": "number",
          "minimum": 0,
          "maximum": 10
        },
        "lowValueProduct": {
          "$ref": "#/definitions/sellers2Commission"
        },
        "platformCommission": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "platforms": {
                "type": "array",
                "items": {
                  "type": "integer"
                }
              },
              "platformNames": {
                "type": "string"
              },
              "value": {
                "$ref": "#/definitions/sellers2Commission"
              }
            }
          }
        }
      }
    },

    "sellers3ProductTemplates": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "region": {
            "type": "string"
          },
          "description": {
            "$ref": "#/definitions/sellers3ProductEurUsValue"
          },
          "addInfo": {
            "$ref": "#/definitions/sellers3ProductEurUsValue"
          }
        }
      }
    }
  },
  "definitions": {
    "sellers2Commission": {
      "type": "object",
      "required": ["percent", "fixed"],
      "properties": {
        "percent": {
          "type": "number",
          "description": "% Fee",
          "minimum": 0.0,
          "maximum": 40
        },
        "fixed": {
          "type": "number",
          "description": "Fixed Fee",
          "minimum": 0.0,
          "maximum": 0.5
        }
      }
    },
    "sellers3TradeSettings": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "platform": {
            "type": "string"
          },
          "regions": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "region": {
                  "type": "string"
                },
                "ratioMin": {
                  "type": "number",
                  "description": "Min Ratio",
                  "minimum": 0.5,
                  "maximum": 1.1
                },
                "ratioMax": {
                  "type": "number",
                  "description": "Max Ratio",
                  "minimum": 0.5,
                  "maximum": 1.1
                }
              }
            }
          }
        }
      }
    },

    "sellers3ProductEurUsValue": {
      "type": "object",
      "required": ["eur", "us"],
      "properties": {
        "eur": {
          "type": "string",
          "description": "You can use [name], [platform] and [autodescr] placeholders"
        },
        "us": {
          "type": "string",
          "description": "You can use [name], [platform] and [autodescr] placeholders"
        }
      }
    }
  }
}

```

Initially my task is to implement all inputs with type number through custom renderer, which prevents scrolling effect whenever user works with input. I create custom input component in accordance with you docs and implemented it in my code like this:

```auto
 const renderers = [
    ...materialRenderers,
    //register custom renderers
    { tester: customInputTester, renderer: CustomRenderers },
  ];

```

In my tester I did this to ensure that all inputs with type number works in accordance with new custom rules:

```auto
import { rankWith, or, isNumberControl } from '@jsonforms/core';

export default rankWith(
  10,
  or(
    isNumberControl,
  )
);

```

And it works fine. First, I also used function **scopeEndsWith** on scopes ending with **fixed** , **percent** and **whenPriceLower**. It also worked, because this scopes exist in uiSchema. Though I can’t reach **ratioMax** and **ratioMin** properties, because they don’t exist in uiSchema, they refer to **sellersTradeSettings** and **sellers2TradeSettings** and then continued in schema through ref as I mentioned previously.

I am sorry for not correctly understanding how it works. I tried multiple functions like this:

`schemaSubPathMatches('/properties/sellersTradeSettings/*/properties/ratioMin', () => true),`

and like this:

```auto
export const isRatioControl = and(
  isControl,
  schemaSubPathMatches('properties/regions/items/properties', (schema) =>
    schemaTypeIs('object')(schema) &&
    schema.hasOwnProperty('ratioMin') &&
    schema.hasOwnProperty('ratioMax')
  )
);

```

and like this:

`schemaSubPathMatches('resellTradeSettings.regions.ratioMin', () => true),`

And it didn’t work, but it seems I misunderstand how custom tester works correctly. So I need some hint how can I handle such a problem or maybe what should I pay my attention to. Maybe I use wrong function to handle what I need. Anyway thanks for cooperation.
