After clicking one parent menu with sub , all other parent menus are expanding with duplicates of existing menu


<!--begin::Menu wrapper-->
<div
id="kt_app_sidebar_menu_wrapper"
class="app-sidebar-wrapper hover-scroll-overlay-y my-5"
data-kt-scroll="true"
data-kt-scroll-activate="true"
data-kt-scroll-height="auto"
data-kt-scroll-dependencies="#kt_app_sidebar_logo, #kt_app_sidebar_footer"
data-kt-scroll-wrappers="#kt_app_sidebar_menu"
data-kt-scroll-offset="5px"
data-kt-scroll-save-state="true"
>
<!--begin::Menu-->
<div
class="menu menu-column menu-rounded menu-sub-indention px-3"
id="#kt_app_sidebar_menu"
data-kt-menu="true"
data-kt-menu-expand="false"
>
<!-- Pages -->
<ng-container *ngIf="isAdmin">
<ng-container *ngFor="let item of ParentMenuList">
<div
class="menu-item"
*ngIf="
willSeparatorPrint(item.SEPARATOR_GROUP_ID, item.MENU_ITEM_ID) == 'Y'
"
>
<div class="menu-content pt-8 pb-2">
<span class="menu-section text-muted text-uppercase fs-8 ls-1">{{
separatorLabel
}}</span>
</div>
</div>
<div
class="menu-item menu-accordion"
data-kt-menu-trigger="click"
(click)="getChild1Menu(item.MENU_ITEM_ID)" routerLinkActive="here show"
>
<span class="menu-link">
<span class="menu-icon">
<span class="svg-icon svg-icon-2" [inlineSVG]="item.ICON_SVG"></span
></span>
<span class="menu-title" >{{ item.MENU_DESCRIPTION }}</span>
<span class="menu-arrow"></span
></span>
<ng-container *ngFor="let child1 of child1List">
<div
class="menu-sub menu-sub-accordion"
(click)="getChild2Menu(child1.MENU_ITEM_ID)"
>
<div class="menu-item menu-accordion" data-kt-menu-trigger="click" routerLinkActive="here show">
<span class="menu-link"
><span class="menu-bullet"
><span class="bullet bullet-dot"></span></span
><span class="menu-title" data-link="child1.MENU_URL">{{
child1.MENU_DESCRIPTION
}}</span
><span class="menu-arrow"></span
></span>

<ng-container *ngFor="let child2 of child2List">
<div
class="menu-sub menu-sub-accordion"
routerLinkActive="menu-active-bg"
>
<div class="menu-item">
<a
class="menu-link without-sub"
routerLinkActive="active"
[routerLink]="child2.MENU_URL"
><span class="menu-bullet"
><span class="bullet bullet-dot"></span></span
><span class="menu-title">{{
child2.MENU_DESCRIPTION
}}</span></a
>
</div>
</div>
</ng-container>
</div>
</div>
</ng-container>
</div>
</ng-container>
</ng-container>
<ng-container *ngIf="isStudent">
<div class="menu-item">
<div class="menu-content pt-8 pb-2">
<span class="menu-section text-muted text-uppercase fs-8 ls-1">{{separatorName}}</span>
</div>
</div>
<ng-container *ngFor="let item of MenuListTeacherStudnet">
<div class="menu-item">
<a class="menu-link without-sub" [routerLink]="item.MENU_URL" routerLinkActive="active"><span class="menu-bullet"><span
class="bullet bullet-dot"></span></span>
<span class="menu-title">{{item.MENU_DESCRIPTION}}</span></a>
</div>
</ng-container>
</ng-container>

</div>
<!--end::Menu-->
</div>
<!--end::Menu wrapper-->
when routerLinkActive="here show" is applied in child1 menu then it duplicates the current parent child menus under other parent menus, all of them get expanded


Text formatting options
Submit
Here's a how to add some HTML formatting to your comment:
  • <pre></pre> for JS codes block
  • <pre lang="html"></pre> for HTML code block
  • <pre lang="scss"></pre> for SCSS code block
  • <pre lang="php"></pre> for PHP code block
  • <code></code> for single line of code
  • <strong></strong> to make things bold
  • <em></em> to emphasize
  • <ul><li></li></ul>  to make list
  • <ol><li></li></ol>  to make ordered list
  • <h3></h3> to make headings
  • <a></a> for links
  • <img> to paste in an image
  • <blockquote></blockquote> to quote somebody
  • happy  :)
  • shocked  :|
  • sad  :(

Replies (2)


import { M } from '@angular/cdk/keycodes';
import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core';
import { Subscription } from 'rxjs';
import { ResponseMessage } from 'src/app/models/response-message';
import { MenuService } from 'src/app/services/menu.service';

@Component({
selector: 'app-sidebar-menu',
templateUrl: './sidebar-menu.component.html',
styleUrls: ['./sidebar-menu.component.scss'],
})
export class SidebarMenuComponent implements OnInit, OnDestroy {
subscriptions: Subscription[] = [];
userCode: any = localStorage.getItem('userCode');
roleId: any = localStorage.getItem('roleId');
userType = localStorage.getItem('userType');
DBmenuList: any;
menuList: any[];
MenuListTeacherStudnet: any[];
ParentMenuList: any;
child1List: any;
child2List: any;
separatorName: string;
separatorLabel: string;

isAdmin: boolean = true;
isStudent: boolean = false;

constructor(
private cdr: ChangeDetectorRef,
private menuService: MenuService
) {
this.menuShow();
this.getDBmenuList();
this.getDBmenuListForTeacherStudent();
}

ngOnInit(): void {}

menuShow(){
if (this.userType == 'Student') {

this.separatorName = 'STUDENT';
this.isAdmin = false;
this.isStudent = true;
} else if (this.userType == 'Teacher') {
this.separatorName = 'TEACHER';
this.isAdmin = false;
this.isStudent = true;
}
}

getDBmenuListForTeacherStudent() {
this.DBmenuList = this.menuService.GetDBMenuList();
this.MenuListTeacherStudnet = this.DBmenuList.filter(
(w) => w.MENU_ITEM_ID != 0 && w.PARENT_MENU_ITEM_ID != 0
&& w.MENU_URL != null
);
}

getDBmenuList() {
this.DBmenuList = this.menuService.GetDBMenuList();
this.ParentMenuList = this.DBmenuList.filter(
(w) => w.PARENT_MENU_ITEM_ID == 0 && w.IS_MENU === 'Y'
);
}

getChild1Menu(MenuItemId: number) {
this.child1List = this.DBmenuList.filter(
(w) => w.PARENT_MENU_ITEM_ID == MenuItemId
);
}

getChild2Menu(MenuItemId: number) {
this.child2List = this.DBmenuList.filter(
(w) => w.PARENT_MENU_ITEM_ID == MenuItemId
);
}

willSeparatorPrint(separatorGroupId: number, menuItemId: number) {
let itemCount: number = this.DBmenuList.filter(
(w) => w.SEPARATOR_GROUP_ID == separatorGroupId && w.IS_MENU == 'N'
).length;

if (itemCount > 0) {
let firstMenuItemId: number = this.DBmenuList.filter(
(w) => w.SEPARATOR_GROUP_ID === separatorGroupId
)[0].MENU_ITEM_ID;
if (firstMenuItemId == menuItemId) {
this.separatorLabel = this.DBmenuList.filter(
(w) => w.SEPARATOR_GROUP_ID === separatorGroupId && w.IS_MENU == 'N'
)[0].MENU_DESCRIPTION;
return 'Y';
} else {
return 'N';
}
} else {
return 'N';
}
}


ngOnDestroy() {
this.subscriptions.forEach((sb) => sb.unsubscribe());
}
}
here is my ts file



Hi,

You can try the following possible solutions:

Remove routerLinkActive from Parent Menus:
Remove the routerLinkActive directive from the parent menus in your template. This directive is intended for identifying the active route, and applying it to parent menus might cause unexpected behavior.

<div
class="menu-item menu-accordion"
data-kt-menu-trigger="click"
(click)="getChild1Menu(item.MENU_ITEM_ID)"
>
<!-- ... your menu content ... -->
</div>


Update Child Menus to Use RouterLinkActive:
Apply the routerLinkActive directive only to the child menus where you want to indicate the active route.

<div class="menu-sub menu-sub-accordion" routerLinkActive="here show">
<div class="menu-item menu-accordion" data-kt-menu-trigger="click" (click)="getChild2Menu(child1.MENU_ITEM_ID)">
<!-- ... your child menu content ... -->
</div>
</div>

Ensure Correct Routes:
Make sure that your routes are correctly defined and match the structure you are using in your routerLink directives.
Use Angular's RouterLink Directive:
Instead of directly using the routerLink attribute, consider using Angular's routerLink directive with an array for better readability and flexibility.

<a class="menu-link without-sub" [routerLink]="[child2.MENU_URL]" routerLinkActive="active">
<!-- ... your menu content ... -->
</a>


This can help in handling complex route structures.

Run Change Detection After Menu Changes:
After updating menu lists (child1List, child2List), you might need to run change detection explicitly using Angular's ChangeDetectorRef to ensure that the changes are reflected in the view.

import { ChangeDetectorRef } from "@angular/core";

// ...

constructor(private cdr: ChangeDetectorRef, private menuService: MenuService) {
// ...
}

// ...

getChild1Menu(MenuItemId: number) {
this.child1List = this.DBmenuList.filter(w => w.PARENT_MENU_ITEM_ID == MenuItemId);
this.cdr.detectChanges(); // Run change detection
}

getChild2Menu(MenuItemId: number) {
this.child2List = this.DBmenuList.filter(w => w.PARENT_MENU_ITEM_ID == MenuItemId);
this.cdr.detectChanges(); // Run change detection
}


Apply these changes and check if the issue persists. If the problem continues, you may need to investigate further, checking the console for any error messages or unexpected behaviors.


Text formatting options
Submit
Here's a how to add some HTML formatting to your comment:
  • <pre></pre> for JS codes block
  • <pre lang="html"></pre> for HTML code block
  • <pre lang="scss"></pre> for SCSS code block
  • <pre lang="php"></pre> for PHP code block
  • <code></code> for single line of code
  • <strong></strong> to make things bold
  • <em></em> to emphasize
  • <ul><li></li></ul>  to make list
  • <ol><li></li></ol>  to make ordered list
  • <h3></h3> to make headings
  • <a></a> for links
  • <img> to paste in an image
  • <blockquote></blockquote> to quote somebody
  • happy  :)
  • shocked  :|
  • sad  :(
Text formatting options
Submit
Here's a how to add some HTML formatting to your comment:
  • <pre></pre> for JS codes block
  • <pre lang="html"></pre> for HTML code block
  • <pre lang="scss"></pre> for SCSS code block
  • <pre lang="php"></pre> for PHP code block
  • <code></code> for single line of code
  • <strong></strong> to make things bold
  • <em></em> to emphasize
  • <ul><li></li></ul>  to make list
  • <ol><li></li></ol>  to make ordered list
  • <h3></h3> to make headings
  • <a></a> for links
  • <img> to paste in an image
  • <blockquote></blockquote> to quote somebody
  • happy  :)
  • shocked  :|
  • sad  :(

React Dev Vacancy

KeenThemes is looking for a Junior React or Vue developer to build awesome apps.
Apply
keenthemes mega bundle