Open Closed

User menu not opening after customizing it. #9709


User avatar
0
pablo@ccalp.net created

After I customize the user menu, it fails to open, I'm getting a console error: ERROR TypeError: Cannot read properties of undefined (reading 'toggle')

This is the code I'm using:

function userMenuFactory(userMenu: UserMenuService, routes: RoutesService, router: Router) {   return () => {     try {       // Defensive check to ensure userMenu service is available       if (!userMenu) {         console.warn('UserMenuService is not available, skipping menu configuration');         return;       }

<br>       userMenu.patchItem(eUserMenuItems.MyAccount, {         action: () => {           const { path } = routes.find(item => item.name === eAccountRouteNames.ManageProfile);           router.navigateByUrl(path);         },       });

<br>       // Remove unwanted menu items with individual error handling       const itemsToRemove = [         eUserMenuItems.LinkedAccounts,         eUserMenuItems.AuthorityDelegation,         eUserMenuItems.ExternalLogins,         eUserMenuItems.SecurityLogs,         eUserMenuItems.Sessions       ];

<br>       itemsToRemove.forEach(item => {           userMenu.removeItem(item);       });

<br>     } catch (error) {       console.error('Error configuring user menu:', error);     }   } }

Using an app initializer

provideAppInitializer(() => {       const initializerFn = (userMenuFactory)(inject(UserMenuService), inject(RoutesService), inject(Router));       return initializerFn();     }),

I also tried doing it in the app.component constructor and OnInit, same results.

This only happens after login, If I refresh the page after I'm logged in, it works, but users are not expected to refresh the page.


16 Answer(s)
  • User Avatar
    0
    AI-Bot created
    Support Team ABP Agent

    To properly customize the user menu in ABP Angular and avoid issues like "Cannot read properties of undefined (reading 'toggle')" after login, you should ensure that your user menu modifications are performed after the menu is fully initialized and the user is authenticated. The error typically occurs if the menu or its dependencies are not ready when you attempt to patch or remove items, especially right after login when the application state is still being established.

    Here is the recommended approach:

    1. Use Angular Lifecycle and Observables
      Instead of running your customization in an app initializer or constructor, subscribe to the authentication/user state and perform menu modifications only when the user is authenticated and the menu is available.

    2. Example Implementation
      Place this logic in your main component (e.g., app.component.ts) inside ngOnInit:

    import { Component, OnInit } from '@angular/core';
       import { UserMenuService, eUserMenuItems } from '@abp/ng.theme.shared';
       import { RoutesService } from '@abp/ng.core';
       import { Router } from '@angular/router';
       import { ConfigStateService } from '@abp/ng.core';
    
       @Component({
         selector: 'app-root',
         templateUrl: './app.component.html',
       })
       export class AppComponent implements OnInit {
         constructor(
           private userMenu: UserMenuService,
           private routes: RoutesService,
           private router: Router,
           private configState: ConfigStateService
         ) {}
    
         ngOnInit(): void {
           this.configState.getOne$('currentUser').subscribe(currentUser => {
             if (currentUser?.isAuthenticated) {
               // Patch MyAccount action
               this.userMenu.patchItem(eUserMenuItems.MyAccount, {
                 action: () => {
                   const { path } = this.routes.find(item => item.name === 'AbpAccount::ManageProfile');
                   this.router.navigateByUrl(path);
                 },
               });
    
               // Remove unwanted items
               [
                 eUserMenuItems.LinkedAccounts,
                 eUserMenuItems.AuthorityDelegation,
                 eUserMenuItems.ExternalLogins,
                 eUserMenuItems.SecurityLogs,
                 eUserMenuItems.Sessions
               ].forEach(item => this.userMenu.removeItem(item));
             }
           });
         }
       }
    
    1. Why This Works

      • The code waits for the user to be authenticated and the menu to be initialized before making changes.
      • This prevents errors related to undefined menu items or missing DOM elements.
      • It also ensures the menu is always in sync with the current user state, even after login without a page refresh.
    2. Do Not Use App Initializer for Menu Customization
      App initializers run before the application is fully bootstrapped and before user/menu state is available, which can cause the issues you observed.

    3. Reference
      Official ABP documentation recommends using the UserMenuService in a component after authentication for menu customization.

    Sources:

    • https://abp.io/docs/latest/framework/ui/angular/theming

    This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.

  • User Avatar
    0
    pablo@ccalp.net created

    I've already tried what the AI is suggesting, still doesn't work. I need to resolve this ASAP. Thanks.

  • User Avatar
    0
    pablo@ccalp.net created

    I think the issue is not because of the customizations, I removed them and the menu is still not being displayed. This is now an urgent matter for us, it is in production. It started happening after the upgrade to 9.2

  • User Avatar
    0
    pablo@ccalp.net created

    Another issue I'm seeing is that the main menu is not collapsing when I select a different menu item, and the scroll bar is gone, If I expand some items I lose visibility and can't scroll down.

  • User Avatar
    0
    sumeyye.kurtulus created
    Support Team Angular Expert

    Hello,

    I can suggest you to override the default navigation to the manage profile page as I mentioned here previously https://abp.io/qa/questions/9674/3a1b61b3-1e0a-ab46-a3ae-8dd97adc6a0d

    @NgModule({
      providers: [
        {
          provide: NAVIGATE_TO_MANAGE_PROFILE,
          useFactory: navigateToManageProfileFactory,
        },
      ],
    })
    export class AppModule {}
    
    export function navigateToManageProfileFactory() {
      const windowService = inject(AbpWindowService);
      const routes = inject(RoutesService);
    
      return () => {
        const { path } = routes.find(item => item.name === eAccountRouteNames.ManageProfile);
        windowService.open(path, 'self');
      };
    }
    

    You will also need to update the patch in your component as follows

    @Component({
      standalone: false,
      selector: 'app-root',
      template: `
        &lt;abp-loader-bar&gt;&lt;/abp-loader-bar&gt;
        &lt;abp-dynamic-layout&gt;&lt;/abp-dynamic-layout&gt;
        &lt;abp-gdpr-cookie-consent&gt;&lt;/abp-gdpr-cookie-consent&gt;
      `,
    })
    export class AppComponent implements OnInit {
      private userMenu = inject(UserMenuService);
      private configState = inject(ConfigStateService);
    
      ngOnInit(): void {
        this.configState.getOne$('currentUser').subscribe(currentUser => {
          if (currentUser?.isAuthenticated) {
            // Patch MyAccount action
            // ⚠️ remove this part and just use the new provider override here
            // this.userMenu.patchItem(eUserMenuItems.MyAccount, {
            //   action: () => {
            //     const { path } = this.routes.find(item => item.name === 'AbpAccount::ManageProfile');
            //     this.router.navigateByUrl(path);
            //   },
            // });
    
            // Remove unwanted items
            [
              eUserMenuItems.LinkedAccounts,
              eUserMenuItems.AuthorityDelegation,
              eUserMenuItems.ExternalLogins,
              eUserMenuItems.SecurityLogs,
              eUserMenuItems.Sessions,
            ].forEach(item => this.userMenu.removeItem(item));
          }
        });
      }
    }
    

    Another issue I'm seeing is that the main menu is not collapsing when I select a different menu item, and the scroll bar is gone, If I expand some items I lose visibility and can't scroll down.

    The problem you mentioned on the sidebar was solved in the previous version https://github.com/abpframework/abp/issues/22301 If you could provide the version for your @volosoft/abp.ng.theme.lepton-x package, I can assist further.

    You can let me know if you need further assistance. Thank you for your cooperation.

  • User Avatar
    0
    pablo@ccalp.net created

  • User Avatar
    0
    pablo@ccalp.net created

    Any updates on the sidebar menu issue?

    The user menu is also still an issue; it is not being displayed on first load. I need to refresh the page, and then it works. I get this message:

  • User Avatar
    0
    pablo@ccalp.net created

    Here's a video of the issues:

    https://app.screencast.com/Xw2IVEfeal1jV

  • User Avatar
    0
    pablo@ccalp.net created

    Any updates

  • User Avatar
    0
    sumeyye.kurtulus created
    Support Team Angular Expert

    Hello again,

    Thank you for providing extra details on your problem.

    If the approach I suggested above does not solve your problem, that would be the best if you could provide a minimal reproducible example so that I could assist you further. Here is my e-mail address: sumeyye.kurtulus@volosoft.com

    I have also checked the version details, and the sidebar problem should not occur in this version.

  • User Avatar
    0
    pablo@ccalp.net created

    The sidebar issue is solved, but the user context menu is still not opening when I use a subdomain; if I log in as the host, it's fine. I created a solution from scratch, and I can confirm the behaviour.

    Is it possible to schedule a Zoom or Teams session to troubleshoot this? I've been struggling for quite some time now, and I need to fix it; it is in production.

    Another option would be to replace the component, but I'm not sure which one is it, I tried eThemeLeptonXComponents.CurrentUser, but seems not to be working.

  • User Avatar
    0
    sumeyye.kurtulus created
    Support Team Angular Expert

    The sidebar issue is solved, but the user context menu is still not opening when I use a subdomain; if I log in as the host, it's fine. I created a solution from scratch, and I can confirm the behaviour.

    Hello again, Thank you for responding and confirming that the sidebar problem does not persist. Also, that would be the best if you could send the solution you created from scratch so that I could help further beforehand. Here is my e-mail address: sumeyye.kurtulus@volosoft.com.

    Another option would be to replace the component, but I'm not sure which one is it, I tried eThemeLeptonXComponents.CurrentUser, but seems not to be working.

    Yes, this is the correct replacement key, however you would not need such replacement for this case.

  • User Avatar
    0
    pablo@ccalp.net created

    Like I said, I just created a solution from scratch using ABP Studio. You need to use a subdomain for the issue to be noticed. Logging in as host works fine, but logging in using a subdomain for the tenant doesn't.

    I made no modifications to the solution, so you should be able to do the same.

  • User Avatar
    0
    sumeyye.kurtulus created
    Support Team Angular Expert

    Hello again,

    Thank you for providing extra details about your problem. We will be looking into this issue for the next patch release. Until we publish a solution, could you try this approach to eliminate the error temporarily?

    // app.component.ts
    export class AppComponent implements OnInit {
      private userMenu = inject(UserMenuService);
      private configState = inject(ConfigStateService);
    
      protected session = inject(SessionStateService);
      protected windowService = inject(AbpWindowService);
      protected readonly localStorageService = inject(AbpLocalStorageService);
    
      ngOnInit(): void {
        const tenant = this.session.getTenant().id || null;
    
        this.configState.getOne$('currentUser').subscribe(currentUser => {
          if (currentUser?.isAuthenticated) {
            // One-time reload when user is authenticated and has tenant
            if (tenant && !this.localStorageService.getItem('reloadForTenant')) {
              this.localStorageService.setItem('reloadForTenant', 'true');
              this.windowService.reloadPage();
            }
    
            [
              eUserMenuItems.LinkedAccounts,
              eUserMenuItems.AuthorityDelegation,
              eUserMenuItems.ExternalLogins,
              eUserMenuItems.SecurityLogs,
              eUserMenuItems.Sessions,
            ].forEach(item => this.userMenu.removeItem(item));
          } else {
            this.localStorageService.removeItem('reloadForTenant');
          }
        });
      }
    }
    

    Thank you for your cooperation.

  • User Avatar
    0
    pablo@ccalp.net created

    Yes, that was my workaround, but customers complained about the user experience. I created my own toolbar using the ng-bootstrap dropdown component for the user profile menu and replaced the component; it works now.

    For the sidebar issue, I had to first include the ng-bundle from the node_modules and then the one compiled from the SCSS source code that has some minor modifications to get it to work. Also, is there an updated guide on how to customize lepton-x from the source, or a better way to do it? The build has a lot of warnings, but it produces an output.

              {
                "input": "node_modules/@volosoft/ngx-lepton-x/assets/css/ng-bundle.css",
                "inject": false,
                "bundleName": "ng-bundle"
              },
              {
                "input": "src/assets/css/pro/libraries/ng-bundle.css",
                "inject": false,
                "bundleName": "ng-bundle"
              },
    
  • User Avatar
    0
    sumeyye.kurtulus created
    Support Team Angular Expert

    Thank you for the response. We will be looking into this problem and propose a solution as soon as possible. You can check the releases for this https://github.com/abpframework/abp/releases

    Also, is there an updated guide on how to customize lepton-x from the source, or a better way to do it? The build has a lot of warnings, but it produces an output.

    If you need to get the source code for your project, you can use this command under your angular directory abp add-package @volosoft/abp.ng.theme.lepton-x --with-source-code

    Thank you for your cooperation.

Boost Your Development
ABP Live Training
Packages
See Trainings
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
Made with ❤️ on ABP v10.0.0-preview. Updated on September 01, 2025, 08:37