0

I am trying to loop through an array from JSON and display the contents more like a side menu. I wrote something like

<ul ng-repeat="(key, value) in menuList.Menu"> <li>{{key}}</li> <ul ng-repeat="(key, value) in value"> <li> {{key}}</li> //second key <ul ng-repeat="(key, value) in value"> <li> {{key}}</li> <ul ng-repeat="(key, value) in value"> <li> {{key}} : {{value}}</li> </ul> </ul> </ul> </ul>

The problem is my second key has both object and array. How do I display the value of Object and loop/ng-repeat just through the array. I cannot modify it with this as it will display the entire content of the array.

 <li> {{key}} : {{value}}</li> 

A part of my JSON for better understanding is given below:

{ "class": 99, "mode" : 0, "Menu": [{ "MenuNum": 1, "MenuItems": [{ "ItemNum": 0, "ItemDesc": "Main Menu", "ActionCode": "-", "ActionInst": "" } , { "ItemNum": 1, "ItemDesc": "BBQ", "ActionCode": "M", "ActionInst": "0992" }, { "ItemNum": 2, "ItemDesc": "Beverages", "ActionCode": "M", "ActionInst": "0992" }] },{ "MenuNum": 2, "MenuItems": [{ "ItemNum": 0, "ItemDesc": "Sub Menu", "ActionCode": "-", "ActionInst": "" }, { "ItemNum": 1, "ItemDesc": "BBQTYPE1", "ActionCode": "P", "ActionInst": "0996" }, { "ItemNum": 2, "ItemDesc": "BeveragesTYPE1", "ActionCode": "P", "ActionInst": "0998" }] }] }

I want the sidebar more like

THIS

5
  • Can you please provide some sample data.CommentedJan 1, 2015 at 10:32
  • Also the DOM structure you expected from your sample data.CommentedJan 1, 2015 at 10:33
  • 1
    I am not sure if I understand your question. It seems like ngSwitch is what you need. Set ngSwitch to check if the last second key is of Object type. If true, insert the DOM designed for the case of Object. Otherwise, insert the DOM designed for the case of Array.CommentedJan 1, 2015 at 11:05
  • Can you give the HTML output you want? It isn't clear from the image what you're looking to produce.CommentedJan 1, 2015 at 15:04
  • the menu should expand and collapse onclick.Here I have expended Menu. Then the 2nd object in it and then the first array in it. I dont think there is a better way to put it. And i cannot follow most of the answers below as my JSON is not as small as this example JSON. it have about 200 menus and each menu have about 10 to 40 menuItems.
    – RBz
    CommentedJan 2, 2015 at 4:08

2 Answers 2

1

Presuming at the moment that you just want the ng-repeat logic, this may be what you are looking for:

 <ul ng-repeat="topMenu in menuList.Menu"> <li> {{$index}} <ul> <li> MenuNum: {{topMenu.MenuNum}} </li> <li> MenuItems <ul ng-repeat="submenu1 in topMenu.MenuItems"> <li> {{$index}} <ul> <li>ItemNum: {{submenu1.ItemNum}}</li> <li>ItemDesc: {{submenu1.ItemDesc}}</li> <li>ActionCode: {{submenu1.ActionCode}}</li> <li>ActionInst: {{submenu1.ActionInst}}</li> </ul> </li> </ul> </li> </ul> </li> </ul> 

If you then want a relatively easy way to do the menu opening/closing, you would probably want to put all this into an Angular accordion. I can probably help you with that if you want.

9
  • This works well. Is this the best way to go about this if I my JSON have 100's of menus and 10 to 50 menuItems? Also i want menu opening and closing. It will be great if you could help me with Angular accordion.
    – RBz
    CommentedJan 2, 2015 at 4:30
  • 100's of menus sounds way too complex. It would be impossible to maintain and would probably overload the DOM to breaking point. Surely you can split up your material into different pages/modules dealing with different subjects. Or to make it maintainable and to keep your sanity you would have to simplify the structure into a form that lends itself to automation/parsing down a tree.
    – mwarren
    CommentedJan 2, 2015 at 8:33
  • You probably need something like Angular Treeview. I wouldn't try reinventing the wheel with something as complex as this.
    – mwarren
    CommentedJan 2, 2015 at 8:42
  • One last thing. Lets assume i have only one or two menus. Here in the code where i am getting {{submenu1.ActionInst}},I need to implement a logic which needs me to do another <ul ng-repeat="submenu1 in topMenu.MenuItems"> But I only need to get the submenu's for MenuItems which equals to submenu1.ActionInst.substring(3). Then I want the normal looping to continue. Is it possible to achieve?
    – RBz
    CommentedJan 2, 2015 at 9:33
  • I'm sure it's possible, but I don't quite understand what you are asking. Are you saying that the structure remains the same, but in some cases you don't want to see the submenu1 stuff unless something equals submenu1.ActionInst.substring(3)? Or are you saying that you will need a further submenu under submenu1 if submenu1.ActionInst.substring(3) equals something?
    – mwarren
    CommentedJan 2, 2015 at 10:19
1

It looks like you're trying to create a list with nested children. How about a recursive pattern which uses ng-include recursively to display all the nested children? Something like this:

<script type="text/ng-template" id="menuTree"> {{ menuItem.name }} <ul ng-if="menuItem.children"> <li ng-repeat="menuItem in menuItem.children" ng-include="'menuTree'"></li> </ul> </script> <ul> <li ng-repeat="menuItem in menuItems" ng-include="'menuTree'"></li> </ul> 

I'm using a slightly different data structure to your code, but you should get the idea. Here's a demo: http://jsfiddle.net/mmmxh8kq/

EDIT:

If the data is as simple as the JSON you posted and you don't need a recursive menu, you could just try this:

<ul> <li ng-repeat="menus in menuList.Menu"> {{ menus.MenuNum }} <ul> <li ng-repeat="menuItems in menus.MenuItems"> {{ menuItems.ItemDesc }} </li> </ul> </li> </ul> 

Demo: http://jsfiddle.net/n4mo80od/

3
  • I have added the JSON. I believe this solution is not for my kind of JSON data structure.
    – RBz
    CommentedJan 1, 2015 at 13:03
  • my JSON is not as small as this example JSON. it have about 200 menus and each menu have about 10 to 40 menuItems. I see below answer is one way to go about it.But the code may get a bit long. But I really didnt got how ng-include may be better. I understand it is something we use inside a view to avoid repeating ourself, in the cases where several views need the same code included. But how is it better than the below mentioned answer?
    – RBz
    CommentedJan 2, 2015 at 4:26
  • The ng-include method is for recursive menus. Say you had a menu which had sub-menu, and that sub-menu had it's own sub-menus - you'd want a way to handle this without repeating yourself too much. If you know that's not the case, a simple ng-repeat will do.CommentedJan 2, 2015 at 10:41

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.