angularprimengmegamenu

Primeng affected by "Error: Cannot find a differ supporting object"


I want to use the megamenu component of primeng, but can't make it work, everytime I load the project, and when its gonna show the menu, it just show the first icon with no text and nothing more, until until i pass upon the menu space for it to show just the first row and in the console I see always the same error:

ERROR (ng:///MegaMenuModule/MegaMenu.ngfactory.js:184) Error: Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays.

the megamenu component depends on un array which contains the definition of the menu: https://www.primefaces.org/primeng/#/megamenu

I look for distintcs docs

  1. https://github.com/angular/angular/issues/6392

  2. Angular: Cannot find a differ supporting object '[object Object]'

  3. p-menu not showing up

(and a lot of others) so finally I deduce the error has to do with a bug in angular to manage arrays of arrays

my code:

/* -------- app.module.ts----------- */ 

import { NgModule, Provider } from '@angular/core';
import { ModuleWithProviders} from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { HttpModule } from '@angular/http';
import { RouterModule, Routes} from '@angular/router';
import { APP_BASE_HREF} from '@angular/common';

import {ConfirmationService, ConfirmDialogModule, Menu, MenuItem} from 'primeng/primeng';
import {PanelModule} from 'primeng/primeng';
import {MenuModule, MegaMenuModule} from 'primeng/primeng';


import { AppComponent } from './app.component';
import { StatisticComponent } from './statistic/statistic.component';
import { DashboardComponent } from './dashboard/dashboard.component';
import { SettingsComponent } from './settings/settings.component';

const appRouter: Routes = [
  { path: '', redirectTo: '/dashboard', pathMatch: 'full' },
  { path: 'dashboard', component: DashboardComponent },
  { path: '**', component: PageNotFoundComponent },
  { path: 'settings', component: SettingsComponent},
];

@NgModule({
  declarations: [
  AppComponent,
  SettingsComponent,
  StatisticComponent,
  DashboardComponent,
  ],
  imports: [
  BrowserModule,
  PanelModule,
  HttpModule,
  BrowserAnimationsModule,
  RouterModule.forRoot(appRouter),
  MenuModule,
  MegaMenuModule
  ],
  exports: [
    RouterModule
  ],
  providers: [{provide: APP_BASE_HREF, useValue: '/'}],
  bootstrap: [AppComponent]
})

export class AppModule {}



/*---------app.component.ts------- */

import {Component, OnInit, ViewChild} from '@angular/core';
import {ActivatedRoute, Router} from '@angular/router';

import {Menu} from 'primeng/components/menu/menu';

import {MenuItem} from 'primeng/primeng';
import {MegaMenuModule, MenuModule } from 'primeng/primeng';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit   {

  contenidoMenu: MenuItem[];

  constructor() {
    this.contenidoMenu = [
     { label: 'Documentos', icon: 'fa-file-text',
       items: [
          {label: 'edición y búsqueda', icon: 'fa-pencil', routerLink: ['/dashboard']},
          {label: 'movimientos', icon: 'fa-exchange', command: (event) => { console.log('movmitns', event); } }
     ]},
      { label: 'Reportes', icon: 'fa-list-alt'
      },
      { label: 'Sistema', icon: 'fa-wrench'
      },
      { label: 'Salir', icon: 'fa-sign-out'
      }
     ];

}



/* -------- app.component.html----------- */ 

<div class="ui-g ui-g-nopad" id="header">
  <div class="ui-sm-12 ui-md-3 ui-g-2">
    <div class="ui-sm12 " id="#top-logo">
      espacio para el  logo y notificaciones
    </div>
    <div class="ui-sm12" id="notifications">
      espacio para notificaciones
    </div>
  </div>

  <div class="ui-sm-12 ui-md-9 ui-g-10">
    <div class="ui-sm12">
      <p-megaMenu [model]="contenidoMenu"> </p-megaMenu>
    </div>
  </div>

</div>

<div class="ui-g ui-g-nopad">

  <div id="content-body" class="ui-md-10 ui-g-nopad ui-md-offset-1 ">

    <router-outlet></router-outlet>

  </div>
</div>

How can I overcome this angular error which is inserted and affecting the behavior of a suite like primeng?


Solution

  • The Error you're getting results of your "contenidoMenu" array. Mega Menu needs an Array like shown in it's Docs with multiple stacked items So you need an Item array with the following Struckture like shown in the Docs:

          [
            {
              label: "MainHeader-lvl-0", icon: 'fa-check',
              items: [ //subheader must be in an MenuItem[][] not as usual an MenuItem[]
                [
                  {
                    label: "SubHeader-lvl-1",
                    items: [
                      { label: "Item-lvl-1.1 add functionality here" },
                      { label: "Item-lvl-1.2 add functionality here" }
                    ]
                  }
                ],
                [
                  {
                    label: "SubHeader-lvl-2",
                    items: [
                      { label: "Item-lvl-2.1 add functionality here" },
                      { label: "Item-lvl-2.2 add functionality here" }
                    ]
                  }
                ]
              ]
            }
          ]
    

    So the SubHeaders must be an Array<MenuItem[]> not as usual an Array<MenuItem> if you fix that strucktural difference it should work. The Problem ist that MegaMenu seems to *NgFor over that Array of Arrays (Array<MenuItem[]>).

    I hope this will help you.