Home > Software design >  nested dictionary into nested list (of checkboxes)
nested dictionary into nested list (of checkboxes)

Time:10-24

I have a nested dictionary with the structure { "1" : [{"a" : ["p", "q"]}, "b", "c", {"d" : ["h", "w"]}] }. Here is the link to the exact data. The depth can go up to any length, but the dept is finite. I am trying to create a nested list (of checkboxes) with the following code.


    import React from "react";

    
    class TagTree extends React.Component{
        render(){
            return(
                <React.Fragment>
                    <ul>
                        { 
                            this.props.tag.map( (t) =>                             
                                <li>
                                    { (typeof(t) === "object")? Object.keys(t) : t }
                                </li>
                            )
                        }
                    </ul>
                </React.Fragment>            
            )
        }
    }


    class TagApp extends React.Component{
        render(){
            return(
                <div>
                    <TagTree tag={this.props.tagList} />
                </div>
            )
        }
    }

    export default TagApp;

Here, the input dictionary is passed as this.props.tagList. I have two problems.

  1. If I recursively create TagTree at the following line

  <li>
      { (typeof(t) === "object")? <TagTree tag={t} /> : t }
  </li>

I get an error

  1. I need to display the key before displaying it's contents.

My thanks for your help. The error is as follows.

Unchecked runtime.lastError: The message port closed before a response was received.
localhost/:1 Unchecked runtime.lastError: The message port closed before a response was received.
localhost/:1 Unchecked runtime.lastError: The message port closed before a response was received.
localhost/:1 Unchecked runtime.lastError: The message port closed before a response was received.
react-jsx-dev-runtime.development.js:87 Warning: Each child in a list should have a unique "key" prop.

Check the render method of `TagTree`. See https://reactjs.org/link/warning-keys for more information.
    at li
    at TagTree (http://localhost:3000/static/js/bundle.js:1301:1)
    at div
    at TagApp (http://localhost:3000/static/js/bundle.js:1330:1)
    at div
    at div
    at McqApp (http://localhost:3000/static/js/bundle.js:952:5)
    at App (http://localhost:3000/static/js/bundle.js:32:1)
printWarning @ react-jsx-dev-runtime.development.js:87
error @ react-jsx-dev-runtime.development.js:61
validateExplicitKey @ react-jsx-dev-runtime.development.js:1078
validateChildKeys @ react-jsx-dev-runtime.development.js:1105
jsxWithValidation @ react-jsx-dev-runtime.development.js:1276
render @ tag.jsx:7
finishClassComponent @ react-dom.development.js:19752
updateClassComponent @ react-dom.development.js:19698
beginWork @ react-dom.development.js:21611
beginWork$1 @ react-dom.development.js:27426
performUnitOfWork @ react-dom.development.js:26557
workLoopSync @ react-dom.development.js:26466
renderRootSync @ react-dom.development.js:26434
performConcurrentWorkOnRoot @ react-dom.development.js:25738
workLoop @ scheduler.development.js:266
flushWork @ scheduler.development.js:239
performWorkUntilDeadline @ scheduler.development.js:533
6tag.jsx:8 Uncaught TypeError: this.props.tag.map is not a function
    at TagTree.render (tag.jsx:8:1)
    at finishClassComponent (react-dom.development.js:19752:1)
    at updateClassComponent (react-dom.development.js:19698:1)
    at beginWork (react-dom.development.js:21611:1)
    at HTMLUnknownElement.callCallback (react-dom.development.js:4164:1)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:4213:1)
    at invokeGuardedCallback (react-dom.development.js:4277:1)
    at beginWork$1 (react-dom.development.js:27451:1)
    at performUnitOfWork (react-dom.development.js:26557:1)
    at workLoopSync (react-dom.development.js:26466:1)
render @ tag.jsx:8
finishClassComponent @ react-dom.development.js:19752
updateClassComponent @ react-dom.development.js:19698
beginWork @ react-dom.development.js:21611
callCallback @ react-dom.development.js:4164
invokeGuardedCallbackDev @ react-dom.development.js:4213
invokeGuardedCallback @ react-dom.development.js:4277
beginWork$1 @ react-dom.development.js:27451
performUnitOfWork @ react-dom.development.js:26557
workLoopSync @ react-dom.development.js:26466
renderRootSync @ react-dom.development.js:26434
performConcurrentWorkOnRoot @ react-dom.development.js:25738
workLoop @ scheduler.development.js:266
flushWork @ scheduler.development.js:239
performWorkUntilDeadline @ scheduler.development.js:533
6tag.jsx:8 Uncaught TypeError: this.props.tag.map is not a function
    at TagTree.render (tag.jsx:8:1)
    at finishClassComponent (react-dom.development.js:19752:1)
    at updateClassComponent (react-dom.development.js:19698:1)
    at beginWork (react-dom.development.js:21611:1)
    at HTMLUnknownElement.callCallback (react-dom.development.js:4164:1)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:4213:1)
    at invokeGuardedCallback (react-dom.development.js:4277:1)
    at beginWork$1 (react-dom.development.js:27451:1)
    at performUnitOfWork (react-dom.development.js:26557:1)
    at workLoopSync (react-dom.development.js:26466:1)
render @ tag.jsx:8
finishClassComponent @ react-dom.development.js:19752
updateClassComponent @ react-dom.development.js:19698
beginWork @ react-dom.development.js:21611
callCallback @ react-dom.development.js:4164
invokeGuardedCallbackDev @ react-dom.development.js:4213
invokeGuardedCallback @ react-dom.development.js:4277
beginWork$1 @ react-dom.development.js:27451
performUnitOfWork @ react-dom.development.js:26557
workLoopSync @ react-dom.development.js:26466
renderRootSync @ react-dom.development.js:26434
recoverFromConcurrentError @ react-dom.development.js:25850
performConcurrentWorkOnRoot @ react-dom.development.js:25750
workLoop @ scheduler.development.js:266
flushWork @ scheduler.development.js:239
performWorkUntilDeadline @ scheduler.development.js:533
6react-dom.development.js:18687 The above error occurred in the <TagTree> component:

    at TagTree (http://localhost:3000/static/js/bundle.js:1301:1)
    at li
    at ul
    at TagTree (http://localhost:3000/static/js/bundle.js:1301:1)
    at div
    at TagApp (http://localhost:3000/static/js/bundle.js:1330:1)
    at div
    at div
    at McqApp (http://localhost:3000/static/js/bundle.js:952:5)
    at App (http://localhost:3000/static/js/bundle.js:32:1)

Consider adding an error boundary to your tree to customize error handling behavior.
Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries.
logCapturedError @ react-dom.development.js:18687
update.callback @ react-dom.development.js:18720
callCallback @ react-dom.development.js:13923
commitUpdateQueue @ react-dom.development.js:13944
commitLayoutEffectOnFiber @ react-dom.development.js:23391
commitLayoutMountEffects_complete @ react-dom.development.js:24688
commitLayoutEffects_begin @ react-dom.development.js:24674
commitLayoutEffects @ react-dom.development.js:24612
commitRootImpl @ react-dom.development.js:26823
commitRoot @ react-dom.development.js:26682
finishConcurrentRender @ react-dom.development.js:25892
performConcurrentWorkOnRoot @ react-dom.development.js:25809
workLoop @ scheduler.development.js:266
flushWork @ scheduler.development.js:239
performWorkUntilDeadline @ scheduler.development.js:533
tag.jsx:8 Uncaught TypeError: this.props.tag.map is not a function
    at TagTree.render (tag.jsx:8:1)
    at finishClassComponent (react-dom.development.js:19752:1)
    at updateClassComponent (react-dom.development.js:19698:1)
    at beginWork (react-dom.development.js:21611:1)
    at beginWork$1 (react-dom.development.js:27426:1)
    at performUnitOfWork (react-dom.development.js:26557:1)
    at workLoopSync (react-dom.development.js:26466:1)
    at renderRootSync (react-dom.development.js:26434:1)
    at recoverFromConcurrentError (react-dom.development.js:25850:1)
    at performConcurrentWorkOnRoot (react-dom.development.js:25750:1)

CodePudding user response:

{ 
    this.props.tag.map( (t) =>                             
        <li key={typeof(t) === "object" ? Object.keys(t)[0] : t}>
          { (typeof(t) === "object")? <TagTree tag={t} /> : t }
        </li>
        )
}

CodePudding user response:

I suggest using a list of objects with fixed keys. For example, each objects could look something like this

courses = [
    {
        "name": "Algebra",
        "topics": [
            {
                "name": "Matrices",
                "topics": [
                    // ...
                ]
            },
            // ...
        ]
    },
    // ...
]

Now recursively descending into this is much easier because every object will always have a "name" and "topics".

  • Related