9

I'm trying to make a menubar using PrimeNG, based on example from http://www.primefaces.org/primeng/#/menubar

I create something like this:

app.component.ts

import {Component} from '@angular/core';
import {MenuBarComponent} from "./menubardemo.component";
@Component({
  selector: 'my-app',
  template: `<h1>My First Angular 2 App</h1><demo></demo>`,
  directives:[MenuBarComponent] })
export class AppComponent { }

menubardemo.components.ts

import {Component, OnInit} from "@angular/core";
import {Menubar, MenuItem} from "primeng/primeng";
@Component({
  selector: 'demo',
  template: `<p-menubar [model]="items"> </p-menubar>`,
  directives: [Menubar] })
export class MenuBarComponent implements OnInit {
  private items:MenuItem[];// you know how to fill this in the "OnInit" method

  ngOnInit() {
    this.items = [
      {
        label: 'File',
        icon: 'fa-file-o',
        items: [{
          label: 'New',
          icon: 'fa-plus',
          items: [
            {label: 'Project'},
            {label: 'Other'},
          ]
        },
          {label: 'Open'},
          {label: 'Quit'}
        ]
      },
      {
        label: 'Edit',
        icon: 'fa-edit',
        items: [
          {label: 'Undo', icon: 'fa-mail-forward'},
          {label: 'Redo', icon: 'fa-mail-reply'}
        ]
      },
      {
        label: 'Help',
        icon: 'fa-question',
        items: [
          {
            label: 'Contents'
          },
          {
            label: 'Search',
            icon: 'fa-search',
            items: [
              {
                label: 'Text',
                items: [
                  {
                    label: 'Workspace'
                  }
                ]
              },
              {
                label: 'File'
              }
            ]
          }
        ]
      },
      {
        label: 'Actions',
        icon: 'fa-gear',
        items: [
          {
            label: 'Edit',
            icon: 'fa-refresh',
            items: [
              {label: 'Save', icon: 'fa-save'},
              {label: 'Update', icon: 'fa-save'},
            ]
          },
          {
            label: 'Other',
            icon: 'fa-phone',
            items: [
              {label: 'Delete', icon: 'fa-minus'}
            ]
          }
        ]
      },
      {
        label: 'Quit', icon: 'fa-minus'
      }
    ];
  }
}

after I checked out the data object is printed on the DOM, but the menubar is not showing.

UPDATE:

index.html

<html>
  <head>
    <title>Angular 2 QuickStart</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" type="text/css" href="node_modules/primeui/themes/omega/theme.css" />
    <link rel="stylesheet" type="text/css" href="node_modules/font-awesome/css/font-awesome.min.css">
    <link rel="stylesheet" type="text/css" href="node_modules/primeui/primeui-ng-all.min.css" />
    <link rel="stylesheet" href="styles.css">

    <!-- Polyfill(s) for older browsers -->
    <script src="node_modules/core-js/client/shim.min.js"></script>

    <script src="node_modules/zone.js/dist/zone.js"></script>
    <script src="node_modules/reflect-metadata/Reflect.js"></script>
    <script src="node_modules/systemjs/dist/system.src.js"></script>
    <script src="node_modules/primeui/primeui-ng-all.min.js"></script>
    <script src="systemjs.config.js"></script>
    <script>
      System.import('app').catch(function(err){ console.error(err); });
    </script>
  </head>

  <body>
    <my-app>Loading...</my-app>
  </body>
</html>

package.json

{
  "name": "angular2-quickstart",
  "version": "1.0.0",
  "description": "QuickStart package.json from the documentation, supplemented with testing support",
  "scripts": {
    "start": "tsc && concurrently \"tsc -w\" \"lite-server\" ",
    "docker-build": "docker build -t ng2-quickstart .",
    "docker": "npm run docker-build && docker run -it --rm -p 3000:3000 -p 3001:3001 ng2-quickstart",
    "pree2e": "npm run webdriver:update",
    "e2e": "tsc && concurrently \"http-server\" \"protractor protractor.config.js\"",
    "lint": "tslint ./app/**/*.ts -t verbose",
    "lite": "lite-server",
    "postinstall": "typings install",
    "test": "tsc && concurrently \"tsc -w\" \"karma start karma.conf.js\"",
    "tsc": "tsc",
    "tsc:w": "tsc -w",
    "typings": "typings",
    "webdriver:update": "webdriver-manager update"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
      "@angular/common":  "2.0.0-rc.1",
      "@angular/compiler":  "2.0.0-rc.1",
      "@angular/core":  "2.0.0-rc.1",
      "@angular/http":  "2.0.0-rc.1",
      "@angular/platform-browser":  "2.0.0-rc.1",
      "@angular/platform-browser-dynamic":  "2.0.0-rc.1",
      "@angular/router":  "2.0.0-rc.1",
      "@angular/router-deprecated":  "2.0.0-rc.1",
      "@angular/upgrade":  "2.0.0-rc.1",
      "systemjs": "0.19.27",
      "es6-shim": "^0.35.0",
      "reflect-metadata": "^0.1.3",
      "rxjs": "5.0.0-beta.6",
      "zone.js": "^0.6.12",
      "angular2-in-memory-web-api": "0.0.7",
      "primeng": "1.0.0-beta.7",
      "primeui": "4.1.12"
  },
  "devDependencies": {
    "concurrently": "^2.0.0",
    "lite-server": "^2.2.0",
    "typescript": "^1.8.10",
    "typings": "^1.0.4",
    "canonical-path": "0.0.2",
    "http-server": "^0.9.0",
    "tslint": "^3.7.4",
    "lodash": "^4.11.1",
    "jasmine-core": "~2.4.1",
    "karma": "^0.13.22",
    "karma-chrome-launcher": "^0.2.3",
    "karma-cli": "^0.1.2",
    "karma-htmlfile-reporter": "^0.2.2",
    "karma-jasmine": "^0.3.8",
    "protractor": "^3.3.0",
    "rimraf": "^2.5.2"
  },
  "repository": {}
}

tsconfig.json

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": false,
    "noImplicitAny": true,
    "suppressImplicitAnyIndexErrors": true
  }
}

systemjs.config.js

/**
 * System configuration for Angular 2 samples
 * Adjust as necessary for your application needs.
 */
(function (global) {

  // map tells the System loader where to look for things
  var map = {
    'app': 'app', // 'dist',

    '@angular': 'node_modules/@angular',
    'angular2-in-memory-web-api': 'node_modules/angular2-in-memory-web-api',
    'rxjs': 'node_modules/rxjs',
    'primeng': 'node_modules/primeng'
  };

  // packages tells the System loader how to load when no filename and/or no extension
  var packages = {
    'app': {main: 'main.js', defaultExtension: 'js'},
    'rxjs': {defaultExtension: 'js'},
    'angular2-in-memory-web-api': {main: 'index.js', defaultExtension: 'js'},
    'primeng': {defaultExtension: 'js'}
  };

  var ngPackageNames = [
    'common',
    'compiler',
    'core',
    'forms',
    'http',
    'platform-browser',
    'platform-browser-dynamic',
    'router',
    'router-deprecated',
    'upgrade',
  ];

  // Individual files (~300 requests):
  function packIndex(pkgName) {
    packages['@angular/' + pkgName] = {main: 'index.js', defaultExtension: 'js'};
  }

  // Bundled (~40 requests):
  function packUmd(pkgName) {
    packages['@angular/' + pkgName] = {main: '/bundles/' + pkgName + '.umd.js', defaultExtension: 'js'};
  }

  // Most environments should use UMD; some (Karma) need the individual index files
  var setPackageConfig = System.packageWithIndex ? packIndex : packUmd;

  // Add package entries for angular packages
  ngPackageNames.forEach(setPackageConfig);

  // No umd for router yet
  packages['@angular/router'] = {main: 'index.js', defaultExtension: 'js'};

  var config = {
    map: map,
    packages: packages
  };

  System.config(config);

})(this);

typings.json

{
  "globalDependencies": {
    "angular-protractor": "registry:dt/angular-protractor#1.5.0+20160425143459",
    "core-js": "registry:dt/core-js#0.0.0+20160602141332",
    "jasmine": "registry:dt/jasmine#2.2.0+20160621224255",
    "node": "registry:dt/node#6.0.0+20160621231320",
    "selenium-webdriver": "registry:dt/selenium-webdriver#2.44.0+20160317120654"
  }
}

enter image description here

enter image description here

wonea
  • 4,783
  • 17
  • 86
  • 139
zho
  • 643
  • 1
  • 12
  • 27

9 Answers9

7

I had the same problem, and searching everywhere, even in this post, I was able to solve it, just configuring a simple empty Route:

app.module.ts

import { RouterModule }   from '@angular/router';

@NgModule({
...
imports: [ RouterModule.forRoot([]), ... ]
...
})

index.html:

<script>document.write('<base href="' + document.location + '" />');</script>
Andrés
  • 119
  • 1
  • 7
1

Try importing both Menubar and MenuItem

import {Menubar,MenuItem} from 'primeng/primeng';

As per your menubardemo.components.ts, you are using only MenuItem.

Sanket
  • 19,295
  • 10
  • 71
  • 82
1

I ran into a similar issue. In my case my application is not using routing, but PrimeNG still requires it. There is an open request to make the router optional, but PrimeNG hasn't responded to that. So I created my own router service:

export class Router
{
   constructor(){}
   public navigate(route: any[]):void
   {
       // Do nothing
   }
}

Then I modified my systemjs.config.js to point @angular/router to my new router. This worked great and I can use the component without needing the router.

tanspac
  • 183
  • 1
  • 1
  • 7
0

any errors in browser console? If any, please post it.

I think that you need to register p-menubar directive to your component. Try to add directives metadata to @Component.

@Component({
  selector: 'my-app',
  template: '<h1>My First Angular 2 App</h1><p-menubar [model]="items"></p-menubar>',
  directives: [PMenubar]
})
Ha Doan
  • 135
  • 1
  • 11
  • nope, there is no error, and i cannot add directives: [PMenubar], they said "Cannot find PMenubar" so i try directives: [Menubar], and still not working... – zho Jun 23 '16 at 08:02
  • 1
    "PMenubar" is not a primeng directive – Sergio Jun 26 '16 at 18:17
0

The documentation is not really complete in this case, you can take a look at the source code and you will find a more complete example: https://github.com/primefaces/primeng/tree/master/showcase/demo/menubar

Given that angular2 is based on components, is better if you extract the menubar in one component and then you can reference it from the AppComponent. For this you first need to create a separate Typescript file of your component, in this case menubardemo.component.ts:

Then you need to add the @Component to the MenubarDemoComponent like this:

import {Component, OnInit} from "@angular/core";
import {Menubar, MenuItem} from "primeng/primeng";
@Component({
    selector: 'demo',
    template: `<p-menubar [model]="items"> </p-menubar>`,
    directives: [Menubar] })
export class MenuBarComponent implements OnInit {     
    private items:MenuItem[];// you know how to fill this in the "OnInit" method
}

And then add it to the AppComponent like this:

import {Component} from '@angular/core'; 
import {MenuBarComponent} from "./menubardemo.component"; 
@Component({   
    selector: 'my-app',   
    template: `<h1>My First Angular 2 App</h1><demo></demo>`,
    directives:[MenuBarComponent] }) 
export class AppComponent { }

One important thing to remember: ALWAYS use " ` " (backtick) when creating a template directly in component's definition, you are using " ' " (single quote) and is incorrect (if your html needs more lines, consider extracting it to other file).

You are instantiating the component: items = new MenubarDemo(), that is also incorrect because components are injected for you automatically, only declare the component in the directives field.

Sergio
  • 3,317
  • 5
  • 32
  • 51
  • An error in particular?, can you add the updated version of your code?? – Sergio Jun 28 '16 at 07:45
  • i follow ur method and it shows some error "zone.js:461 Unhandled Promise rejection: EXCEPTION: Error in ./Menubar class Menubar - inline template:3:12 ORIGINAL EXCEPTION: No provider for Router!" something wrong with my code? – zho Jun 28 '16 at 14:00
  • oh that looks like another issue, well try this solution that worked for me some time ago: http://stackoverflow.com/questions/34535163/angular-2-router-no-base-href-set , let me know if it works – Sergio Jun 28 '16 at 14:13
  • I REALLY will appreciate if you can udpate your question with ALL your code, it will be easier for me to help you. – Sergio Jun 28 '16 at 14:14
  • yes, you should add the changes from the answer that I linked (the base tag + additional config in bootstrap) – Sergio Jun 28 '16 at 15:37
  • Did you add the base tag and add the bootstrap configuration? Update your code with those changes – Sergio Jun 30 '16 at 06:48
  • i'm sorry sergio, i dont get it, what do you mean by base tag and bootstrap configuration? however i clone this code from angular2-quickstart over here https://github.com/angular/quickstart and i haven't change anything except all of files that i mention in the post, i have added some configuration (.JSON) at the post as well. well, this is my first time on typescript programming. – zho Jun 30 '16 at 10:01
  • I linked this: http://stackoverflow.com/questions/34535163/angular-2-router-no-base-href-set because is exactly the error you have, and angular2 is asking you to configure the router. Add the changes that are described in the linked response and try again. If that doesn't work, post your updated code here and I will keep trying to help you. – Sergio Jun 30 '16 at 12:42
0

Looking at the error "No provider for Router" looks like an issue with PrimeNG component not having angular2 Router configured, but I didn't confirm, it would be nice if anyone digs into this.

Anyway, I had this problem, added some basic routing and it worked, so I'm sharing it, it should be something like this:

main.ts

import { bootstrap }    from '@angular/platform-browser-dynamic';
import { AppComponent } from './app.component';

import { provide } from '@angular/core';
import { APP_ROUTER_PROVIDERS } from './app.routes';
import {APP_BASE_HREF} from '@angular/common';

bootstrap(AppComponent, [APP_ROUTER_PROVIDERS,provide(APP_BASE_HREF, {useValue : '/' })]);

app.component.ts

import { Component } from '@angular/core';
import {MenuBarComponent} from "./menubardemo.component";
import {ROUTER_DIRECTIVES} from '@angular/router';

@Component({
  selector: 'my-app',
  directives: [ROUTER_DIRECTIVES, MenuBarComponent],
  template: `
    <h1>My First Angular 2 App</h1>
    <demo></demo>
    <div>
      <router-outlet></router-outlet>
    </div>     
  `
})
export class AppComponent { }

new: app.routes.ts

import {provideRouter,RouterConfig} from '@angular/router';
import {ContentComponent} from './content.component'

export const routes: RouterConfig = [
    {path: '', component: ContentComponent}
];

export const APP_ROUTER_PROVIDERS = [
  provideRouter(routes)
];

new: content.component.ts (default component)

import { Component } from '@angular/core';

@Component({
  selector: 'content',
  template: '<div><p>This is some content</p></div>'
})
export class ContentComponent { }
Tony
  • 2,473
  • 3
  • 23
  • 32
0

i´ve encountered the same problem. I just can't import MenuItem from primeng/primeng, i have even tried to search where is the interface, in fact it is inside the "common" folder, in primeng version 17, the file its called api.d.ts , i tried to copy the interface declaration and use it in my Menu, but for now im just waiting for a solution. Meanwhile you can try this , and it will work, just declare items as any type.

      private items: any[];

That´s it.

uajov6
  • 413
  • 7
  • 13
0

I just figured this out I believe.

You need to import the MenuModule in the app.module.ts

//app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';
import {MenuModule} from 'primeng/primeng';



import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule,
    MenuModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

This should fix your problem.

0

May be this will help some one. In my case I forgot to add the libraries in angular.json file

Step 1: In app.module.ts code:

@NgModule({
    declarations: [AppComponent, HeaderComponent, MenubarComponent],
    imports: [
        BrowserModule,
        BrowserAnimationsModule,
        AppRoutingModule,
        MenuModule,
        MenubarModule,
        BreadcrumbModule,
    ],

 Note: Make sure you have added the Menubar module and import it like below

import { MenubarModule } from 'primeng/menubar';

Step 2: If you have menubar in separate component

export class MenubarComponent implements OnInit {
    items: MenuItem[];

And make sure you have the following import

import { MenuItem } from 'primeng/api';

Step 3: This was the missing part for me. If you did the npm installation of primeng then in

In angular.json file: Make sure you have the necessary primeng libraries like below

under architect build

"styles": [
                        "node_modules/primeicons/primeicons.css",
                        "node_modules/primeng/resources/themes/nova-light/theme.css",
                        "node_modules/primeng/resources/primeng.min.css",   
                        "src/styles.scss"
                    ],

This will display the menubar for sure

Ragavan Rajan
  • 4,171
  • 1
  • 25
  • 43