zho
zho

Reputation: 653

How to make PrimeNG Menubar component work?

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

Upvotes: 9

Views: 24489

Answers (9)

Ragavan Rajan
Ragavan Rajan

Reputation: 4397

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

Upvotes: 0

Ben Gummelt
Ben Gummelt

Reputation: 9

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.

Upvotes: 0

tanspac
tanspac

Reputation: 183

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.

Upvotes: 1

Tony
Tony

Reputation: 2533

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 { }

Upvotes: 0

Andr&#233;s
Andr&#233;s

Reputation: 119

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>

Upvotes: 7

uajov6
uajov6

Reputation: 443

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.

Upvotes: 0

Sergio
Sergio

Reputation: 3387

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.

Upvotes: 0

Sanket
Sanket

Reputation: 20017

Try importing both Menubar and MenuItem

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

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

Upvotes: 1

Ha Doan
Ha Doan

Reputation: 135

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]
})

Upvotes: 0

Related Questions