child watches parent = infinite recursion
See original GitHub issueGeneral information
- json-editor version: 1.4.0-beta.0
Schema has an array of objects. I want one field in those objects to be an enum list of all values of another field in the same array.
Example of a valid use case: an array of objects describing software releases. A release has a “version” field and a “replaced by” field, where “replaced by” should be an enum of all existing versions.
Expected behavior:
It should be possible for a property to watch its parent.
Actual behavior
Nesting a watch like this causes infinite recursion. When you touch the parent array, it notifies the watching child property, which then bubbles up onChange(), which when it reaches the parent, notifies the child, which…
Steps to reproduce the behavior
Add an item to the array and you get Maximum call stack size exceeded
.
{
"type": "object",
"properties": {
"things": {
"type": "array",
"items": {
"type": "object",
"properties": {
"prop1": {
"type": "string"
},
"prop2": {
"type": "string",
"watch": {
"tings": "root.things"
},
"enumSource": [
{
"source": "tings",
"value": "{{item.prop1}}"
}
]
}
}
}
}
}
}
Looks like we need a smart way to break the loop. I started to tackle this by flagging the watch as “looped” when setting up watches if watcher.path.startsWith(watched.path)
and then trying to break the event cascade.
Issue Analytics
- State:
- Created 4 years ago
- Comments:8
Top GitHub Comments
The recursion starts here: https://github.com/json-editor/json-editor/blob/0ca9b61cf02a4fc4ba55327c5e02bca58771341a/src/editors/select.js#L350
With the above change to
setupWatchListeners()
(just settingwatchLoop
), I can stop the bubbling right there:With this change, things seem to work OK, selects are being dynamically populated across all array members without issues and editor’s global onChange() I am using, seems to stay intact. Maybe this needs some clever logic to still bubble, but sending some termination condition / flag / message / loop counter up the loop so that this happens only once, however right now, for me my problem is fixed.
…but don’t blame me if it turns out later that this accidentally summons Cthulhu into someone’s pond.
@wowczarek While adding JavaScript callback support for enumSource https://github.com/json-editor/json-editor/pull/476/commits/7c26fe77b989daa6c7fa7900dbc4dc765b52df9b, I noticed that in the
filter
callback the watched property is available. So it might be possible to filter out the parent somehow. (If you return an empty string, the item will be ignored/filtered)Example data available in the filter template: