question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

child watches parent = infinite recursion

See original GitHub issue

General 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

Direct link to example: https://json-editor.github.io/json-editor/?schema=N4IgLgngDgpiBcID2AjAVjAxmEAaEUATkrIWAJYwDOCoYAFuQHYDmN8d0ciAhoYTwh4Q5MDAC27TrATJ0WHPiIkYZSlILEoARlrgusqmELMWIAL5KtAJj2QZiIydbCA7jzCZ6d0+xDEkMAA6Bl8LfBgmAFdxAGUkKMJMbgBtUCoEpO5wMPwANx4AGyjs4GBRCSDlHXNzCwBdWqbzIA==&value=N4IgLgFglgdg5gZxALgNoF0C+Q==&lib_switcher=&prompt_before_delete&upload=function(a,b,c){console.log("Upload handler required for upload editor")}&theme=bootstrap2&iconlib=fontawesome4&object_layout=normal&show_errors=interaction

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:closed
  • Created 4 years ago
  • Comments:8

github_iconTop GitHub Comments

1reaction
wowczarekcommented, Aug 15, 2019

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 setting watchLoop), I can stop the bubbling right there:

      if(this.parent && !this.jsoneditor.watchLoop) this.parent.onChildEditorChange(this);
      else this.jsoneditor.onChange();

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.

0reactions
pmk65commented, Aug 17, 2019

@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:

{
  "i": 1,
  "item": {
    "text": "Green"
  },
  "watched": {
    "colors": [
      {
        "text": "Red"
      },
      {
        "text": "Green"
      }
    ],
    "self": ""
  }
}
Read more comments on GitHub >

github_iconTop Results From Across the Web

Defensive Code to prevent Infinite Recursion in Parent/Child ...
One way would be to include a collection of visited nodes in the recursive call. If visited before you are in a cycle....
Read more >
Part 11 - Solving Infinite Recursion using ... - YouTube
Step by Step here: https://www.kindsonthegenius.com/hibernate-relationship-tutorial-onetomany-and-manytoone/Part 1 - Introduction to ...
Read more >
More recursion - parents and children - Desktop Liberation
More recursion – parents and children · 1 Adding parent links · 2 Identifying siblings · 3 and the result … · 4...
Read more >
Campus Parent - Bulloch County Schools
If you need help to complete the annual Student Update and Information Verification, please watch our Infinite Campus Parent How-to Video.
Read more >
Infinite Campus Portal for Parents and Students
Our Infinite Campus parent portal is the best way to stay informed about all aspects of your child's education. Elementary: parents/guardians can access ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found