Base solution for your next web application
Open Closed

Angular menu dynamic from API + routing url questions #6654


User avatar
0
peabaw created

Hi there

Two questions regarding menu and routing in angular + api that I cannot seem to find a way around.

  1. Menu:

I am dynamically generating a menu depending on the "Forms" that are in the system. The problem is that the menu is rendered before the API-call is done, so no dynamic menu items shows up. That is until you mouse over the left meny, then they appers.

Do I need to load them earlier? Where? How? Or could I force it to wait for the API call to finish?

app-navigation.service.ts:

getMenu(): AppMenu {
        var res: Array<AppMenuItem> = [];
        res.push(new AppMenuItem('Dashboard', 'Pages.Administration.Host.Dashboard', 'flaticon-line-graph', '/app/admin/hostDashboard'),
            new AppMenuItem('Dashboard', 'Pages.Tenant.Dashboard', 'flaticon-line-graph', '/app/main/dashboard'),
            new AppMenuItem('Tenants', 'Pages.Tenants', 'flaticon-list-3', '/app/admin/tenants'),
            new AppMenuItem('Editions', 'Pages.Editions', 'flaticon-app', '/app/admin/editions')
        );
        
        this._formsServiceProxy.getFormsForMenu().forEach(element =>
            { 
                element.forEach(item => 
                    {
                        var subItems = [];
                        subItems.push(new AppMenuItem(this._appLocalizationService.l('Incidents'), 'Pages.Incidents', 'flaticon-more', '/app/main/registrations/incidents'));
                        subItems.push(new AppMenuItem(this._appLocalizationService.l('CreateNewIncident') + ' ' + this._appLocalizationService.l(item.form.translationId), 'Pages.Incidents.Create', 'flaticon-add', '/app/main/registrations/incident/new', [], false, {form: item.form.id}))
                        res.push(new AppMenuItem(this._appLocalizationService.l(item.form.translationId), '', 'flaticon-more', '', subItems));
                    });
            }
        );
                
        return new AppMenu('MainMenu', 'MainMenu', res);
    }
  1. Routing/Menu selected item

The dynamically generated menu items are a "parent" and two children. The first child is going to a list of already created form items (/app/main/registrations/incidents) and the other to the CreateNewFormItem (/app/main/registrations/incident/new). The listing and creation/editing are the same component regardless of Form.

Example:

Menu:

Form 1 List CreateNew Form 2 List CreateNew

The problem I have is that when you click "Form 1->List" BOTH "Form1->List" and "Form2->List" becomes menu selected (as they have the same routing url). I have tried to google angular routing and if there are any "placeholders/dummy" attributes to use but have not found anything.

imports: [
        RouterModule.forChild([
            {
                path: '',
                children: [
                    { path: 'registrations/incident/new', component: CreateOrEditIncidentComponent, data: { permission: 'Pages.Incidents' } },
                    { path: 'registrations/incident/edit/:incidentId', component: CreateOrEditIncidentComponent, data: { permission: 'Pages.Incidents' } },
                    { path: 'registrations/incidents', component: IncidentsComponent, data: { permission: 'Pages.Incidents' } },
                    { path: 'dashboard', component: DashboardComponent, data: { permission: 'Pages.Tenant.Dashboard' } }
                ]
            }
        ])
    ],

How can I make the url unique AND at the same time route the calls to the same path? Is it possible the routing way or is it someting for the menu to handle instead?


6 Answer(s)
  • User Avatar
    0
    peabaw created

    Typical, you ask the question and then possibly solves it... I'll close this and reopen in case I does not work.

  • User Avatar
    0
    peabaw created

    Second part is solved. First part is unfortunately still an issue.

  • User Avatar
    0
    ismcagdas created
    Support Team

    You can load them in side-bar-menu.component.ts, add a new method to appNavigationService to include your dynamic menu items into original menu definition.

    https://github.com/aspnetzero/aspnet-zero-core/blob/dev/angular/src/app/shared/layout/nav/side-bar-menu.component.ts#L37

  • User Avatar
    0
    peabaw created

    So I changed the side-bar-menu's init to this:

    ngOnInit() {
            var res: Array<AppMenuItem> = [];
            this._formsServiceProxy.getFormsForMenu().forEach(element =>
                { 
                    element.forEach(item => 
                        {
                            var subItems = [];
                            subItems.push(new AppMenuItem(this._appLocalizationService.l('Incidents'), 'Pages.Incidents', 'flaticon-more', '/app/main/registrations/incidents/' + item.form.area, [], false, {formArea: item.form.area}));
                            subItems.push(new AppMenuItem(this._appLocalizationService.l('CreateNewIncident') + ' ' + this._appLocalizationService.l(item.form.translationId), 'Pages.Incidents.Create', 'flaticon-add', '/app/main/registrations/incident/new/' + item.form.area, [], false, {form: item.form.id}))
                            res.push(new AppMenuItem(this._appLocalizationService.l(item.form.translationId), '', 'flaticon-more', '', subItems));
                        });
                }
            );
            
            this.menu = this._appNavigationService.getMenu(res);
    
            this.currentRouteUrl = this.router.url.split(/[?#]/)[0];
    
            this.router.events
                .pipe(filter(event => event instanceof NavigationEnd))
                .subscribe(event => this.currentRouteUrl = this.router.url.split(/[?#]/)[0]);
        }
    

    app-navigation getMenu:

    getMenu(dynamicMenuItems: Array<AppMenuItem>): AppMenu {
            // TODO: Api call to _formsServiceProxy.getFormsForMenu() loads too late, not visible in gui on initial loading /AW
            var res: Array<AppMenuItem> = [];
            res.push(new AppMenuItem('Dashboard', 'Pages.Administration.Host.Dashboard', 'flaticon-line-graph', '/app/admin/hostDashboard'),
                new AppMenuItem('Dashboard', 'Pages.Tenant.Dashboard', 'flaticon-line-graph', '/app/main/dashboard'),
                new AppMenuItem('Tenants', 'Pages.Tenants', 'flaticon-list-3', '/app/admin/tenants'),
                new AppMenuItem('Editions', 'Pages.Editions', 'flaticon-app', '/app/admin/editions')
            );
            
            dynamicMenuItems.forEach(element => res.push(element));
    

    Now the menu items do not even show up, not even on mouse over. Also tried to execute the api-call in the constructor, but no change.

    Did I miss something?

  • User Avatar
    0
    ismcagdas created
    Support Team

    @peabaw

    Could you share the entire content of getMenu method ?

  • User Avatar
    0
    ismcagdas created
    Support Team

    @peabaw

    Have you solved your problem ?