Stack Overflow Asked on November 24, 2020
I have the following sample data set which comes from server.
[
{
subMenuId: 1,
submenu: 'Users',
menu: 'Administration',
url: '/pms/admin/usrs-dsh',
icon: 'fas fa-cogs',
},
{
subMenuId: 2,
submenu: 'Roles',
menu: 'Administration',
url: '/pms/admin/roles-dsh',
icon: 'fas fa-cogs',
},
{
subMenuId: 3,
submenu: 'Menu Items',
menu: 'Administration',
url: '/pms/admin/menus-dsh',
icon: 'fas fa-cogs',
},
{
subMenuId: 4,
submenu: 'Banks',
menu: 'Administration',
url: '/pms/admin/banks-dsh',
icon: 'fas fa-cogs',
},
{
subMenuId: 5,
submenu: 'Branches',
menu: 'Administration',
url: '/pms/admin/branches-dsh',
icon: 'fas fa-cogs',
},
{
subMenuId: 6,
submenu: 'Dashboard',
menu: 'PD3',
url: '/pms/pd3/dsh',
icon: 'fas fa-cogs',
},
];
And I want to display this data like this. But currently when displaying data main level values repeat with each sub level value.
Expected Output:
Html file:
<tr *ngFor="let m of userPermissions;">
<td>
<label class="ml-3 form-check-label">{{m.menu}}</label>
</td>
<td>
<div>
<input (change)="changeSubMenus($event, m.menu,m.subMenuId)" type="checkbox" class="ml-0 form-check-input">
<label class="ml-3 form-check-label">{{m.submenu}}</label><br>
</div>
</td>
</tr>
TS file:
getMenus(){
this.userPermissions = this.adminService.allMenus;
this.userPermissions.forEach((val) =>{
// console.log(val)
// TODO: remove multiple main level values and display sub level values with one main level value
})
}
Is there any way to achieve this.
Thanks
You need to modify the objects in the array to achieve the requirement you want. You can use reduce for that like below.
You need to have an object structure like the below, to make things simpler
modifiedMenu = [{
menu: < Main Menu 1 > ,
subMenu: [ < submenu item > , < submenu item > , ...]
}, {
menu: < Main Menu 2 > ,
subMenu: [ < submenu item > , < submenu item > , ...]
}, ...]
So, the original one is
userPermissions = this.menus.reduce((acc, ele) => {
if (acc.length === 0) {
acc.push(this.getModifiedMainMenu(ele));
return acc;
} else {
const existedMenu = acc.find(m => m.menu === ele.menu);
if (existedMenu) {
existedMenu.subMenu.push(this.getSubMenu(ele));
return acc;
} else {
acc.push(this.getModifiedMainMenu(ele));
return acc;
}
}
}, []);
getModifiedMainMenu(obj) {
return {
menu: obj.menu,
subMenu: [this.getSubMenu(obj)]
};
}
getSubMenu(obj) {
return {
menu: obj.menu,
subMenuId: obj.subMenuId,
submenu: obj.submenu,
url: obj.url,
icon: obj.icon
};
}
And in the template file, now you need 2 ngFor
s to loop main menu items and respective submenu items like below
<tr *ngFor="let m of userPermissions;">
<td>
<label class="ml-3 form-check-label">{{m.menu}}</label>
</td>
<td>
<div *ngFor="let subMenu of m.subMenu">
<input (change)="changeSubMenus($event, subMenu.menu, subMenu.subMenuId)" type="checkbox" class="ml-0 form-check-input">
<label class="ml-3 form-check-label">{{subMenu.submenu}}</label>
</div>
</td>
</tr>
Correct answer by Sivakumar Tadisetti on November 24, 2020
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP