Adding PrimeNG UI components to Angular CLI projects

Angular 2 CLI is a scaffolding tool and code generator that can be used for the real world projects. It saves you a lot of typing and spares you from worrying about config files for TypeScript compiler, testing frameworks, project bundler (it uses Webpack), and deployment.

PrimeNG is an excellent library of 70+ Angular 2 UI components. In this blog I’ll list the steps you need to perform to generate new project with Angular CLI and add PrimeNG library to this project.

If you don’t have Angular CLI installed yet, install it globally:

npm install @angular/cli -g

In the terminal window generate a new project, e.g. primeng_with_cli. Since I just want Angular CLI to generate only app compnent and module files, I’ll specify the option to generate inline template and styles and don’t bother with the test spec:


ng new primeng_with_cli --it --is --spec=false

Change to the newly created directory

 
cd primeng_with_cli

Add font awesome and PrimeNG as dependencies in package.json, e.g.


"font-awesome": "^4.6.3",

"primeng": "^1.0.0-beta.20",

Since the package.json was modified, install the above dependencies:

npm install

PrimeNG requires certain global styles so its components look pretty. Angular CLI projects have a config file angular-cli.json, where you can configure project settings, and in particular it has the property styles, which is the right place to add global style. Yes, I’m talking about the style tages that you’d add in the index.html in a regular Web app.

Angular CLI generate an empty file style.css and you need to add three more CSS file that are needed for PrimeNG:


"styles": [
    
  "styles.css",

  "../node_modules/primeng/resources/themes/omega/theme.css",

  "../node_modules/font-awesome/css/font-awesome.min.css",

  "../node_modules/primeng/resources/primeng.min.css"

] 

For sanity check run your new app by entering the following command in the terminal window:

ng serve

Open the app in the browser at 
http://localhost:4200, and Webpack dev server will happily render the single-page app with the text app works! This is a basic app that Angular CLI generated for you.

Now you need to modify the code in the generated dir app.component with the code that uses PrimeNG components. You can take the sample code from this blog. You’ll need to add required PrimeNG components to imports and declarations in the application module file app.module.ts.

The dev version of the app works, and now let’s see the prod version of this cool app. To prepare a production build run this command:

ng build --prod

Angular CLI will create bundles and will deploy all the files in the dist directory of your project. Take a peek into this directory and you’ll see the bundles that are available as .js files as well as their gzipped versions. The question is, how can we serve the existing gzipped files without having the web server do it for us? A simple solution is to install a static Node server that knows how to do it. Just add node-static package as dev dependency in package.json and install it:


"node-static": "^0.7.9" 
npm install

Finally, add the following npm script command in scripts section in package.json:



"serve:dist": "static dist -H '{\"Cache-Control\": \"no-cache, must-revalidate\"}' -z"

Start the static server and it’ll serve the optimized app on port 8080:



npm run serve:dist

NOTE: Creators of PrimeNG promised to add AoT support in the release candidate that will be available within a couple of weeks. When it’s done, you’ll be able to create smaller bundles by running this command:

ng build --prod --aot

That’s all folks!

Advertisements

23 thoughts on “Adding PrimeNG UI components to Angular CLI projects

  1. Yakov,

    Is it possible to use cli on existing (non-cli) project, like add ngPrime library to it?

    I think, it would be great to add a bonus chapter to your book talking about NgPrime and other component libraries, and maybe extend your Weather sample there (to include NgPrime Table or DataGrid and a LineChart). That kind of info is totally missing from all Angular2 books existing today.
    I am planning to try that in my project.

    Thank you,
    Oleg.

    1. If you wan to use CLI, you need to generate the project with Angular CLI and then copy the code (except config files) from your old app to the newly generate one.

      Our Angular book is written and no more chapters will be added. My previous blog shows how to add PrimeNG components to a non-cli project.

  2. Yakov,

    Enlightening piece. will the setup process be the same if i want to use a different UI librar, say ng-lightning??

    Thanks

  3. Hi Yakov,
    Thanks for this useful article. I stumbled on the same question for a few days and solved it before finding your article by chance. I nevertheless learned a few more tricks with it.
    Two comments, though:
    1. In my version of ng-cli (1.0.0-beta.19-3), the option “–spec=false” has no effect: .spec.ts files get generated anyway and the help advertised by ng does not work (“ng new –help”). I haven’t found yet in the ng documentation how to achieve this effect
    2. By using “npm install font-awesome –save” you get the effect of your 2 successive commands at once (update of package.json *and* installation). Of course, same applies to the other packages.
    Keep up with the good job!
    Kind regards

  4. when i tried “npm run serve:dist” I got error, I tried many times, it was really frustrated.
    the error is: (primengwithcli is my project name)
    Failed at the primengwithcli@0.0.0 serve:dist script ‘static dist -H ‘{“Cache-Control”: “no-cache, must-revalidate”}’ -z’.

    1. Make sure that the static server is installed in your project (chek the directory node_module/.bin).

      Then try to run the following command from a command prompt and see if you’ll get a more descriptive error:

      node_module/.bin/static dist -H ‘{\”Cache-Control\”: \”no-cache, must-revalidate\”}’ -z

      Don’t copy/paste this command to avoid issues with the wrong quote symbols.

  5. Hi Yakov Fain ,

    I am not able to use the schedule component with my angular cli project.
    I get the error TypeError: this.schedule.fullCalendar is not a function

    i have also included “scripts”: [“../node_modules/primeui/primeui-ng-all.min.js”], in angular-cli.json

  6. Hi Yakov,

    I’m hoping you can shed some light on the issue of running the Karma tests using Angular CLI. I have searched the web and also asked in the forum http://forum.primefaces.org/viewtopic.php?f=35&t=49177 but can’t get past it. These tests worked fine but then when I add any PrimeNG component, it fails with something like:

    p-calendar’ is not a known element.
    1. If ‘p-calendar’ is an Angular component, then verify that it is part of this module.
    2. If ‘p-calendar’ is a Web Component then add “CUSTOM_ELEMENTS_SCHEMA” to the ‘@NgModule.schemas’ of this component to suppress this message.

    A copy of my spec file is in the PrimeNG forum post.

        1. I’m not sure if this is the right fix but I was able to eliminate the error by also adding schemas: [CUSTOM_ELEMENTS_SCHEMA] to my app.components.spec.ts file

  7. CUSTOM_ELEMENTS_SCHEMA is intended for interoperability with non-Angular components. For example if you are using a custom HTML element , Angular’s template compiler knows nothing about it and reports an error. With CUSTOM_ELEMENTS_SCHEMA you can tell Angular to stop complaining about and just trust you that it will be available in the runtime. However you shouldn’t use CUSTOM_ELEMENTS_SCHEMA for Angular components (including 3rd-party). They should be either declared in your NgModule, or imported along with other NgModules.

    Your test looks 100% correct. I quickly wrote a test with PrimeNG Calendar (respecting version numbers), no problems as well. So I suspect two things:
    1. Either it’s a configuration issue (possible, but unlikely).
    2. Or isn’t the root problem. Do you use any other 3rd-party components inside ManualTransactionsComponent (or its children)? Could you provide the entire error log?

    1. Thank you for your help on this. I am not using any other 3rd party. I am not able to post the log on this site. Can I email it to you?

      1. Well, after further review, it looks like user error. I had neglected to add my other PrimeNG modules to the imports property of TestBed.configureTestingModule.

        However, I also had to add the modules to the imports property in my app.component.spec.ts file. It seems that this file needs all references to any component I use on my other components. Is this the correct behavior? I am thinking just to removing app.component.spec.ts file since the tests seemed to be irrelevant.

        1. Correct, that’s what I was assuming while mentioning other 3rd-party components. Your testing module is isolated from the rest of NgModules in your application, so you need to import everything ManualTransactionsComponent depends on in the testing module as well.

  8. Anton,

    What are your thoughts on keeping the app.component.spec.ts file? Does it really give us any insight to the testing? It just seems to be a pain that you have to duplicate your modules in both your component spec plus the app.component.spec.ts file.

    1. If it’s a container component that renders a router outlet or just lists other components, personally, I wouldn’t bother adding the spec. I’m not religious about tests :). But generally tests might be very verbose and often exceed the amount of main application code.

  9. Hi Yakov,

    Any idea how to fix this error:
    Template parse errors:
    ‘p-dropdown’ is not a known element:
    1. If ‘p-dropdown’ is an Angular component and it has ‘options’ input, then verify that it is part of this module.
    Can’t bind to ‘options’ since it isn’t a known property of ‘p-dropdown’.

    package.json:
    “primeng”: “2.0.0”

    environment –
    angular-cli: 1.0.0-beta.24
    node: 6.1.0
    os: darwin x64

    app.module.ts :
    import { DropdownModule } from ‘primeng/components/dropdown/dropdown’
    @NgModule({
    imports: [DropdownModule]

    Sample.Component.ts:
    import { SelectItem } from ‘primeng/components/common/api’;
    export class SampleComponent
    cities: SelectItem[];
    selectedCity: string;
    constructor() {
    this.cities = [];
    this.cities.push({label:’Select City’, value:null});
    this.cities.push({label:’New York’, value:{id:1, name: ‘New York’, code: ‘NY’}});
    this.cities.push({label:’Rome’, value:{id:2, name: ‘Rome’, code: ‘RM’}});
    }
    Sample.Component.html
    My First PrimeNG App

    What am I missing in the configuration. Any help is appreciated.

  10. Hi Yakov,
    npm run serve:dist gave me this error:
    > static dist -H ‘{“Cache-Control”: “no-cache, must-revalidate”}’ -z
    undefined:1
    ‘{Cache-Control:
    ^
    SyntaxError: Unexpected token ‘ in JSON at position 0

    Has anyone seen this error?

      1. Correction to my last post:
        It only works if I run it like this:
        node_module/.bin/static dist -H ‘{”Cache-Control”: ”no-cache, must-revalidate”}’ -z

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s