TyForHelpDude
TyForHelpDude

Reputation: 5002

creating nested elements with recursive function

This is interfaces of object, and target data is array of this object so it

looks like;
export interface IMenuModel {
  Id: number
  itemName: string;
  parentId?: number;
  childItems: IMenuModel[];
}

sample contents example;

[ {itemName:"League",.. childItems: [{itemName:"Fixture",.. childitems:[...]]}] } ] 

and this is the sample list I want to create;

<li className="dropdown">
    <a href="#" className="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">League<span className="caret" /></a>
    <ul className="dropdown-menu" role="menu">
        <li><a href="#">Fixture</a>
            <ul className="dropdown-menu" role="menu">
                <li>
                  <a href="#">item name</a>
                </li>
                <li>
                  <a href="#">item name</a>
                </li>
            </ul>
        </li>
    </ul>
</li>

this is what I tried to do it but works only one deep;

listLoop(items:IMenuModel[]):JSX.Element[] {
    var menuJsx:JSX.Element[] = items.map((item)=>{
      return (<li key={item.Id} className="dropdown">
        <a href="#" className="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false"> {item.itemName}<span className="caret" /></a>
      </li>);
    })
    return menuJsx;
  }

how can I create a recursive function to achieve this?

Upvotes: 2

Views: 743

Answers (2)

Mayank Shukla
Mayank Shukla

Reputation: 104379

Write it like this:

 _createList(item){
      return item.map((el,i)=>{
          return <div key={i}>
                   {el.name}
                   {el.child.length ? this._createList(el.child) : null}
                 </div>
      })
  }

  render() {
    return (
      <div >
        {this._createList(item)}
      </div>
    )
  }

Check the working jsfiddle: https://jsfiddle.net/mayankshukla5031/wxrc24o1/

var item=[
    {
      	name: '1',
      	child: []
    },
    {
    	name: '2',
    	child: [
    		{
    			name: '2.1',
    			child: [
    				{
    					name: '2.1.1',
    					child:[
    						{
    							name: '2.1.1.1',
    							child: [],
    						}
    					]
    				}
    			]
    		},
    		{
    			name: '2.2',
    			child: []
    		}
    	]
    }
];

class App extends React.Component {
  constructor() {
    super();
  }
  
  _createList(item){
      return item.map((el,i)=>{
          return <div key={i}>
                   {el.name}
                   {el.child.length ? this._createList(el.child) : null}
                 </div>
      })
  }

  render() {
    return (
      <div >
        {this._createList(item)}
      </div>
    )
  }
}

ReactDOM.render(<App />, document.getElementById('container'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id="container"/>

Upvotes: 2

FuzzyTree
FuzzyTree

Reputation: 32392

Add a recursive call to listLoop if the item.childItems is not empty:

listLoop(items:IMenuModel[]):JSX.Element[] {
    var menuJsx:JSX.Element[] = items.map((item)=>{
        return (<li key={item.Id} className="dropdown">
        <a href="#" className="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false"> {item.itemName}<span className="caret" /></a>
            {items.childItems && items.childItems.length &&
                <ul className="dropdown-menu" role="menu">
                {this.listLoop(items.childItems)}
                </ul>
            }
        </li>);
    })
    return menuJsx;
}

Upvotes: 0

Related Questions