Showing posts with label angular 2/4. Show all posts
Showing posts with label angular 2/4. Show all posts


September 22, 2018
Native Angular directives for Bootstrap


Table of contents

  1. Getting Started
  2. Installation instructions
  3. Usage & Demo
  4. API
  5. Troubleshooting
  6. Contributing
  7. License

Getting Started

ngx-bootstrap contains all core (and not only) Bootstrap components powered by Angular. So you don't need to include original JS components, but we are using markup and css provided by Bootstrap.

Installation instructions

Install ngx-bootstrap from npm
 npm install ngx-bootstrap --save
You will need bootstrap styles (Bootstrap 3)

Or Bootstrap 4

To enable bootstrap 4 theme templates in ngx-bootstrap, please read this.

Usage & Demo

Main source of API documentation and usage scenarios available here:
Additionally you can find demos and docs deployed from latest code with angular v4 and angular v5
Server side rendered version of this documentation available here


Check demo page for API reference

How to use it with:

How to build lib for development

First time
  • clone repository
  • npm install
  • npm run test it will build the lib and create a link in node_modules
To run bootstrap 3 and 4 demo:
  • npm run demo.serve to serve local demo. This is for testing only, without watchers.
For local development run
  • npm run in first terminal
  • ng serve in second
If you want to run the demo with Angular Universal:
  • npm run demo.serve-universal


So if you are in trouble, here's where you can look for help.
The best place to ask questions is on StackOverflow (under the ngx-bootstrap tag) You can also join our Slack channel and link your stackoverflow question there. But try to avoid asking generic help questions directly on Slack since they can easily get lost in the chat. You can also search among the existing GitHub issues.
If, and only if, none of the above helped, please open a new issue.

Note: Special thanks to Valor Software
Disclaimer: The blog is created to share angular directives information to geek, curious Angular Developers.


September 11, 2018
Angular2 Directive For React Component


After 0.3.0 or higher, ng2-react has been changed to @ngui/react. Here are the changes;
  • Module ng2-react is changed to @ngui/react
  • Direvtive ng2-react is changed to ngui-react
  • Class name Ng2React is changed to NguiReact

With @ngui/react, we can do the following from Angular2

  • Pass read-only props to React component
  • Call a function in React component
  • Fire event in React componet
  • Set state of React componet
You need more? Please log a feature requirement

How Does It Work

  1. Angular renders ngui-react component with the following attributes;
  • reactComponent, A React component to render. Let's call it as MyComp.
  • reactProps, react props for the React component, MyComp.
  • reactState, the initial state to be used by MyComp
  1. ngui-react create and render React component using;
  • React.createElement()
  • React.render()

Access ReactJS properties

You can access react element and instance from Angular component.
  • reactElement: the react element from React.createElement()
  • reactInstance: the react instance from React.render()


  1. install @ngui/react
     $ npm install @ngui/react --save  
  2. import NguiReactModule to your AppModule
  3.  import { NgModule } from '@angular/core';  
      import { FormsModule } from "@angular/forms";  
      import { BrowserModule } from '@angular/platform-browser';  
      import { AppComponent } from './app.component';  
      import { NguiReactModule } from '@ngui/react';  
       imports: [BrowserModule, FormsModule, NguiReactModule],  
       declarations: [AppComponent],  
       bootstrap: [ AppComponent ]  
      export class AppModule { }  
For full example, please check out app directory to see the example of
  • app.module.ts
  • and app.component.ts

Example Usage


 class Hello extends React.Component {  
  render() {  
   return <div>Hello {}</div>;  


 import { Component, ViewChild } from '@angular/core';  
 import { Hello } from "./hello"; // This is a react component  
  selector: 'my-app',  
  template: `  
    [reactProps]="{name:'angular2 react wrapper'}">  

Note: Special thanks to ng2-ui


Disclaimer: The blog is created to share angular directives information to geek, curious Angular Developers.


July 05, 2018
:telephone_receiver: Microservice framework for RabbitMQ written in TypeScript


coconspirators is a microservice framework for RabbitMQ written in TypeScript. Under the hood it uses qmqp.node, the battle-tested AMQP client, to communicate with RabbitMQ and has best-practices baked in. Features include:
  • Simple API for subscribing, publish and replying
  • DI Friendly
  • TypeScript First



 npm i coconspirators --S  


 npm run build  


 import { Queue, AmqpQueue, AmqpClient } from 'coconspirators';  
 export class AmqpServer {  
  connection: Promise<any>;  
  constructor(public client: AmqpClient, logger: Logger) {  
   this.connection = this.client.connect();  
   client.on('connected', () => console.log('connected!'));  
   client.on('disconnected', () => console.log('disconnected!'));  
 interface ZooMessage {  
  animal: string;  
  name: 'health'  
  contentType: 'application/json'  
 export class HealthQueue extends AmqpQueue<ZooMessage> {  
  constructor(client: AmqpClient) { super(client); }  
 export class HealthChecker {  
  constructor(queue: HealthQueue) {  
   this.queue.publish({ hi: true });  
   this.queue.subscribe((message: ZooMessage) => {  
    console.log('message', message);  


ngx-datatable is a Swimlane open-source project; we believe in giving back to the open-source community by sharing some of the projects we build for our application. Swimlane is an automated cyber security operations and incident response platform that enables cyber security teams to leverage threat intelligence, speed up incident response and automate security operations.

Note: Special thanks to Swimlane


Disclaimer: The blog is created to share angular directives information to geek, curious Angular Developers.


June 27, 2018

Web Notifications Powered by RxJS for Angular 2

Easily create and handle desktop notifications in Angular 2


Install @ngrx/notify from npm:

npm install @ngrx/notify --save

Setup the providers, optionally providing global notification options:

import { NOTIFY_PROVIDERS, NOTIFY_GLOBAL_OPTIONS } from '@ngrx/notify';

bootstrap(App, [
  { provide: NOTIFY_GLOBAL_OPTIONS, multi: true, useValue: { /* global options here */ } }


Requesting Notification Permission

Before creating notifications, you must resolve the app's notification permission:
class AppComponent {
  constructor(notify: Notify) {
    notify.requestPermission().subscribe(permission => {
      if (permission) {
        // continue

Creating a Notification

To create a notification observable, call the open() method with a title and optional config. The notification will be opened when you subscribe to the observable and will close after you unsubscribe from it. The observable will emit the instance of the notification every time it is clicked on:'Hello world!', options)
  // Automatically close the notification after 5 seconds
  // Close the notification after it has been clicked once
  .subscribe(notification => {


See the documentation on MDN for available options.



June 09, 2018

ngx-modialog (previously `angular2-modal`)

This project is looking for a new maintainer, see [#414]( for details.

ngx-modialog version 5.x.x works with angular 5.x.x


Version 4.x.x contains some breaking changes, please see the [CHANGELOG](./

Library has been renamed from version 3.0.2

Modal / Dialog implementation for angular. - Easy to use API via Fluent API Presets (alert, prompt, confirm) - Can render Component's, TemplateRef's and literal string - Extendable via plugins. - Easy to use typescript modal.alert() .title('Hello World') .body('In Angular') .open(); Available plugins: - Bootstrap (3 & 4) - [Vex 3 & 4](


bash npm install ngx-modialog

Basic plunker playground (bootstrap plugin):

ngx-modialog @ 4.x.x

ngx-modialog @ 3.x.x

Quick start

**In your application root module definition add `ModalModule` and the plugin you want to use:** We will use the bootstrap plugin (`BootstrapModalModule`) for this introduction. ```typescript import { ModalModule } from 'ngx-modialog'; import { BootstrapModalModule } from 'ngx-modialog/plugins/bootstrap'; // lots of code... @NgModule({ bootstrap: [ /* ... */ ], declarations: [ /* ... */ ], imports: [ /* ... */ ModalModule.forRoot(), BootstrapModalModule ], }) export class AppModule { /* lots of code... */ } ```

In any angular component or service inject the `Modal` service and open a modal:

typescript import { Component, ViewContainerRef } from '@angular/core'; import { Overlay } from 'ngx-modialog'; import { Modal } from 'ngx-modialog/plugins/bootstrap'; @Component({ selector: 'my-app', template: `<button (click)="onClick()">Alert</button>` }) export class AppComponent { constructor(public modal: Modal) { } onClick() { const dialogRef = this.modal.alert() .size('lg') .showClose(true) .title('A simple Alert style modal window') .body(` <h4>Alert is a classic (title/body/footer) 1 button modal window that does not block.</h4> <b>Configuration:</b> <ul> <li>Non blocking (click anywhere outside to dismiss)</li> <li>Size large</li> <li>Dismissed with default keyboard key (ESC)</li> <li>Close wth button click</li> <li>HTML content</li> </ul>`) .open(); dialogRef.result .then( result => alert(`The result is: ${result}`) ); } } If you are using **ngx-modialog** version 3.X.X or below, `open()` returned a promise so replace the last 2 lines with: typescript dialogRef .then( dialogRef => { dialogRef.result.then( result => alert(`The result is: ${result}`); }); We are using the `alert()` method, one of 3 (prompt, confirm)) fluent-api methods we call `drop-ins` We then use the `result` property to wait for the modal closing event. **Notes:** - Fluent API methods (drop-ins) are pre-configured (presets) methods that allow easy configuration and execution, you can create custom presets - see the demo application. - For more control use the `open()` method, which is used by all drop in's internally. - We import the `Modal` service from the plugin and not from the root library. Import from the root should work but being explicit allow using multiple plugins. ## Demo App The Demo application is a full implementation of the library with the native plugins. View it at []( The demo application is [part of this repository]( and it is a great place to learn by example.

Bootstrap / VEX features:

- Customizable with components, Presets and more... - Select cancel/quit key. - Cascading modals. - Element blocking. - Blocking / Non blocking modal. - Modal as a component, replace the content by supplying a custom component. The demo application comes with a [dynamic modal generator]( for the **Boostrap** plugin ## Plugins Plugins serve as a concrete UI implementation for a modal. It can be an implementation for a known library (e.g: bootstrap) or something completely unique While `ngx-modialog` has some built in plugins it is also possible to use external plugins from NPM, if someone decide to build one. > Built a plugin? I would love to know :) # Known bugs ### The dialog closes when removing the target DOM element in a click event ref [issue#111]( To avoid this problem use `event.stopPropagation();` or put the element removal inside a `setTimeout` call # HELP WANTED! As a sole author I find it difficult to maintain multiple open source projects. As a result it is hard for me to replay rapidly to requests/help/etc... If you would like to contribute, please contact me, the community will thank you. You can contribute via: - Implementing features & Bug fixes - Documentation (Extremely important) - Issue management


February 02, 2018
The idea is simple: Add a loading bar / progress bar whenever an XHR request goes out in angular. Multiple requests within the same time period get bundled together such that each response increments the progress bar by the appropriate amount.
This is mostly cool because you simply include it in your app, and it works. There's no complicated setup, and no need to maintain the state of the loading bar; it's all handled automatically by the interceptor.

Requirements: AngularJS 1.2+

File Size: 2.4Kb minified, 0.5Kb gzipped


  1. include the loading bar as a dependency for your app. If you want animations, include ngAnimate as well. note: ngAnimate is optional
     angular.module('myApp', ['angular-loading-bar', 'ngAnimate'])  
  2. include the supplied JS and CSS file (or create your own CSS to override defaults).
     <link rel='stylesheet' href='build/loading-bar.min.css' type='text/css' media='all' />  
     <script type='text/javascript' src='build/loading-bar.min.js'></script>  
  3. That's it -- you're done!

via bower:

 $ bower install angular-loading-bar  

via npm:

 $ npm install angular-loading-bar  

via CDN:

  <link rel='stylesheet' href='//' type='text/css' media='all' />  
  <script type='text/javascript' src='//'></script>  

Why I created this

There are a couple projects similar to this out there, but none were ideal for me. All implementations I've seen require that you maintain state on behalf of the loading bar. In other words, you're setting the value of the loading/progress bar manually from potentially many different locations. This becomes complicated when you have a very large application with several services all making independent XHR requests. It becomes even more complicated if you want these services to be loosly coupled.
Additionally, Angular was created as a highly testable framework, so it pains me to see Angular modules without tests. That is not the case here as this loading bar ships with 100% code coverage.
Goals for this project:
  1. Make it automatic
  2. Unit tests, 100% coverage
  3. Must work well with ngAnimate
  4. Must be styled via external CSS (not inline)
  5. No jQuery dependencies


Turn the spinner on or off:

The insertion of the spinner can be controlled through configuration. It's on by default, but if you'd like to turn it off, simply configure the service:
 angular.module('myApp', ['angular-loading-bar'])  
  .config(['cfpLoadingBarProvider', function(cfpLoadingBarProvider) {  
   cfpLoadingBarProvider.includeSpinner = false;  

Turn the loading bar on or off:

Like the spinner configuration above, the loading bar can also be turned off for cases where you only want the spinner:
 angular.module('myApp', ['angular-loading-bar'])  
  .config(['cfpLoadingBarProvider', function(cfpLoadingBarProvider) {  
   cfpLoadingBarProvider.includeBar = false;  

Customize the template:

If you'd like to replace the default HTML template you can configure it by providing inline HTML as a string:
 angular.module('myApp', ['angular-loading-bar'])  
  .config(['cfpLoadingBarProvider', function(cfpLoadingBarProvider) {  
   cfpLoadingBarProvider.spinnerTemplate = '<div><span class="fa fa-spinner">Loading...</div>';  

Position the template:

If you'd like to position the loadingBar or spinner, provide a CSS selector to the element you'd like the template injected into. The default is the

 angular.module('myApp', ['angular-loading-bar'])  
  .config(['cfpLoadingBarProvider', function(cfpLoadingBarProvider) {  
   cfpLoadingBarProvider.parentSelector = '#loading-bar-container';  
   cfpLoadingBarProvider.spinnerTemplate = '<div><span class="fa fa-spinner">Custom Loading Message...</div>';  

 <div id="loading-bar-container"></div>  
Also keep in mind you'll likely want to change the CSS to reflect it's new position, so you'll need to override the default CSS:
 #loading-bar .bar {  
  position: relative;  

Latency Threshold

By default, the loading bar will only display after it has been waiting for a response for over 100ms. This helps keep things feeling snappy, and avoids the annoyingness of showing a loading bar every few seconds on really chatty applications. This threshold is totally configurable:
 angular.module('myApp', ['angular-loading-bar'])  
  .config(['cfpLoadingBarProvider', function(cfpLoadingBarProvider) {  
   cfpLoadingBarProvider.latencyThreshold = 500;  

Ignoring particular XHR requests:

The loading bar can also be forced to ignore certain requests, for example, when long-polling or periodically sending debugging information back to the server.
 // ignore a particular $http GET:  
 $http.get('/status', {  
  ignoreLoadingBar: true  
 // ignore a particular $http POST. Note: POST and GET have different  
 // method signatures:  
 $'/save', data, {  
  ignoreLoadingBar: true  

 // ignore particular $resource requests:  
 .factory('Restaurant', function($resource) {  
  return $resource('/api/restaurant/:id', {id: '@id'}, {  
   query: {  
    method: 'GET',  
    isArray: true,  
    ignoreLoadingBar: true  

How it works:

This library is split into two modules, an $http interceptor, and a service:

The interceptor simply listens for all outgoing XHR requests, and then instructs the loadingBar service to start, stop, and increment accordingly. There is no public API for the interceptor. It can be used stand-alone by including cfp.loadingBarInterceptor as a dependency for your module.

The service is responsible for the presentation of the loading bar. It injects the loading bar into the DOM, adjusts the width whenever set() is called, and complete()s the whole show by removing the loading bar from the DOM.

Service API (advanced usage)

Under normal circumstances you won't need to use this. However, if you wish to use the loading bar without the interceptor, you can do that as well. Simply include the loading bar service as a dependency instead of the main angular-loading-bar module:

 angular.module('myApp', ['cfp.loadingBar'])  

 // will insert the loading bar into the DOM, and display its progress at 1%.  
 // It will automatically call `inc()` repeatedly to give the illusion that the page load is progressing.;  
 // increments the loading bar by a random amount.  
 // It is important to note that the auto incrementing will begin to slow down as  
 // the progress increases. This is to prevent the loading bar from appearing  
 // completed (or almost complete) before the XHR request has responded.  
 cfpLoadingBar.set(0.3) // Set the loading bar to 30%  
 cfpLoadingBar.status() // Returns the loading bar's progress.  
 // -> 0.3  
 // Set the loading bar's progress to 100%, and then remove it from the DOM.  


The loading bar broadcasts the following events over $rootScope allowing further customization:

cfpLoadingBar:loading triggered upon each XHR request that is not already cached

cfpLoadingBar:loaded triggered each time an XHR request recieves a response (either successful or error)

cfpLoadingBar:started triggered once upon the first XHR request. Will trigger again if another request goes out after cfpLoadingBar:completed has triggered.

cfpLoadingBar:completed triggered once when the all XHR requests have returned (either successfully or not)


Credit goes to rstacruz for his excellent nProgress.

Note: Special thanks to Wes Cruver
Disclaimer: The blog is created to share angular directives information to geek, curious Angular Developers.


February 01, 2018
This is the implementation of the concept described in Authentication in AngularJS (or similar) based application.
There are releases for both AngularJS 1.0.x and 1.2.x, see releases.
Launch demo here or switch to gh-pages branch for source code of the demo.


  • Install via bower: bower install --save angular-http-auth
  • ...or via npm: npm install --save angular-http-auth
  • Include as a dependency in your app: angular.module('myApp', ['http-auth-interceptor'])


This module installs $http interceptor and provides the authService.

The $http interceptor does the following: the configuration object (this is the requested URL, payload and parameters) of every HTTP 401 response is buffered and everytime it happens, the event:auth-loginRequired message is broadcasted from $rootScope.

The authService has only 2 methods: loginConfirmed() and loginCancelled().
You are responsible to invoke loginConfirmed() after user logs in. You may optionally pass in a data argument to this method which will be passed on to the loginConfirmed $broadcast. This may be useful, for example if you need to pass through details of the user that was logged in. The authService will then retry all the requests previously failed due to HTTP 401 response.
You are responsible to invoke loginCancelled() when authentication has been invalidated. You may optionally pass in a data argument to this method which will be passed on to the loginCancelled $broadcast. The authService will cancel all pending requests previously failed and buffered due to HTTP 401 response.
In the event that a requested resource returns an HTTP 403 response (i.e. the user is authenticated but not authorized to access the resource), the user's request is discarded and the event:auth-forbidden message is broadcast from $rootScope.

Ignoring the 401 interceptor

Sometimes you might not want the interceptor to intercept a request even if one returns 401 or 403. In a case like this you can add ignoreAuthModule: true to the request config. A common use case for this would be, for example, a login request which returns 401 if the login credentials are invalid.

Typical use case:

  • somewhere (some service or controller) the: $http(...).then(function(response) { do-something-with-response }) is invoked,
  • the response of that requests is a HTTP 401,
  • http-auth-interceptor captures the initial request and broadcasts event:auth-loginRequired,
  • your application intercepts this to e.g. show a login dialog:
  • DO NOT REDIRECT anywhere (you can hide your forms), just show login dialog
  • once your application figures out the authentication is OK, call: authService.loginConfirmed(),
  • your initial failed request will now be retried and when proper response is finally received, the function(response) {do-something-with-response} will fire,
  • your application will continue as nothing had happened.

Sending data to listeners:

You can supply additional data to observers across your application who are listening for event:auth-loginConfirmed and event:auth-loginCancelled:
  $scope.$on('event:auth-loginConfirmed', function(event, data){  
       $rootScope.isLoggedin = true;  
  $scope.$on('event:auth-loginCancelled', function(event, data){  
   $rootScope.isLoggedin = false;  
Use the authService.loginConfirmed([data]) and authService.loginCancelled([data]) methods to emit data with your login and logout events.

Updating $http(config):

Successful login means that the previous request are ready to be fired again, however now that login has occurred certain aspects of the previous requests might need to be modified on the fly. This is particularly important in a token based authentication scheme where an authorization token should be added to the header.
The loginConfirmed method supports the injection of an Updater function that will apply changes to the http config object.
 authService.loginConfirmed([data], [Updater-Function])  
 //application of tokens to previously fired requests:  
 var token = response.token;  
 authService.loginConfirmed('success', function(config){  
  config.headers["Authorization"] = token;  
  return config;  
The initial failed request will now be retried, all queued http requests will be recalculated using the Updater-Function.
It is also possible to stop specific request from being retried, by returning false from the Updater-Function:
 authService.loginConfirmed('success', function(config){  
  if (shouldSkipRetryOnSuccess(config))  
   return false;  
  return config;  

Note: Special thanks to Witold Szczerba
Disclaimer: The blog is created to share angular directives information to geek, curious Angular Developers.


December 25, 2017
Angular 2 multiselect dropdown component for web applications. Easy to integrate and use.

Table of Contents

1. Getting Started
2. Installation
3. Usage
4. Templates
5. Template Driven Forms support
6. Reactive Forms support
7. Settings configuration
8. Callbacks and events

Getting Started


  • The Mutiselect Dropdown package is published on the npm Registry.
  • Install the package : npm install angular2-multiselect-dropdown
  • Once installed import AngularMultiSelectModule from the installed package into your module as follows:


Import AngularMultiSelectModule into NgModule in app.module.ts
 import { AngularMultiSelectModule } from 'angular2-multiselect-dropdown/angular2-multiselect-dropdown';  
  // ...  
  imports: [  
  // ...  
Declare the component data variables and options in your component where you want to consume the dropdown component.
 import { Component, OnInit } from '@angular/core';  
 export class AppComponent implements OnInit {  
   dropdownList = [];  
   selectedItems = [];  
   dropdownSettings = {};  
     this.dropdownList = [  
                {"id":5,"itemName":"South Korea"},  
     this.selectedItems = [  
                 {"id":5,"itemName":"South Korea"}  
     this.dropdownSettings = {   
                  singleSelection: false,   
                  text:"Select Countries",  
                  selectAllText:'Select All',  
                  unSelectAllText:'UnSelect All',  
                  enableSearchFilter: true,  
                  classes:"myclass custom-class"  
   onSelectAll(items: any){  
   onDeSelectAll(items: any){  
Add the following component tag in you template
 <angular2-multiselect [data]="dropdownList" [(ngModel)]="selectedItems"   

Template - For custom html of menu item

 <angular2-multiselect [data]="dropdownList" [(ngModel)]="selectedItems" [settings]="dropdownSettings">  
      <ng-template let-item="item">  
       <label style="color: #333;min-width: 150px;">{{item.itemName}}</label>  
       <img [src]="item.image" style="width: 30px; border: 1px solid #efefef;margin-right: 20px;" />  
       <label>Capital - {{}}</label>  

Template Driven Forms support

 <form (ngSubmit)="onSubmit()" #loginForm="ngForm" style="border: 1px solid #ccc; padding: 10px;">  
     <div class="form-group">  
       <label for="name">Skills</label>  
       <angular2-multiselect [data]="itemList" [(ngModel)]="formModel.skills"   
                  (onDeSelectAll)="onDeSelectAll($event)" name="skills">  

 formModel = {  
     name: '',  
     email: '',  
     skills: [{ "id": 1, "itemName": "Angular" }]  

Reactive Forms support

 <form [formGroup]="userForm" novalidate style="border: 1px solid #ccc; padding: 10px;">  
     <div class="form-group">  
       <label for="name">Skills</label>  
       <angular2-multiselect [data]="itemList" [(ngModel)]="selectedItems"   
                  (onDeSelectAll)="onDeSelectAll($event)" formControlName="skills">  

 userForm: FormGroup;  
 this.userForm ={  
       name: '',  
       email: ['', Validators.required],  
       skills: [[], Validators.required]  


The following list of settings are supported by the component. Configure the settings to meet your requirement.
Setting Type Description Default Value
singleSelection Boolean To set the dropdown for single item selection only. false
text String Text to be show in the dropdown, when no items are selected. 'Select'
enableCheckAll Boolean Enable the option to select all items in list false
selectAllText String Text to display as the label of select all option Select All
unSelectAllText String Text to display as the label of unSelect option UnSelect All
enableSearchFilter Boolean Enable filter option for the list. false
maxHeight Number Set maximum height of the dropdown list in px. 300
badgeShowLimit Number Limit the number of badges/items to show in the input field. If not set will show all selected. All
classes String Custom classes to the dropdown component. Classes are added to the dropdown selector tag. To add multiple classes, the value should be space separated class names. ''
limitSelection Number Limit the selection of number of items from the dropdown list. Once the limit is reached, all unselected items gets disabled. none
disabled Boolean Disable the dropdown false
searchPlaceholderText String Custom text for the search placeholder text. Default value would be 'Search' 'Search'
groupBy String Name of the field by which the list should be grouped. none
searchAutofocus Boolean Autofocus search input field true

Callback Methods

  • onSelect - Return the selected item on selection. Example : (onSelect)="onItemSelect($event)"
  • onDeSelect - Return the un-selected item on un-selecting. Example : (onDeSelect)="OnItemDeSelect($event)"
  • onSelectAll - Return the list of all selected items. Example : (onSelectAll)="onSelectAll($event)"
  • onDeSelectAll - Returns an empty array. Example : (onDeSelectAll)="onDeSelectAll($event)"
  • onOpen - Callback method fired after the dropdown opens Example : (onOpen)="onOpen($event)"
  • onClose - Callback method, fired when the dropdown is closed Example : (onClose)="onClose($event)"

Note: Special thanks to Pradeep Terli
Disclaimer: The blog is created to share angular directives information to geek, curious Angular Developers.


December 24, 2017
Create map based applications using cesium and angular2 components. Focusing on high performance with easy usage. Check out our Demo that contains small app built with angular-cesium.

Getting started

  • install angular-cesium:
     $ npm install --save angular-cesium
  • Angular cli

  • If you didn't installed Angular CLI yet:
     $ npm install -g @angular/cli
  • start new project:
     $ ng new PROJECT_NAME
  • Import and add AngularCesiumModule to your app root module:
     import { AngularCesiumModule } from 'angular-cesium';
    // ....
     declarations: [],
     imports: [
      // ...
     bootstrap: [AppComponent]
    export class AppModule {
  • AngularCesiumModule configuration

  • The main module should be loaded with .forRoot() in order to make the module perform enhancements to Cesium, However, the module can be loaded with out calling forRoot().
  • .forRoot() excepts an optional option object of type ModuleConfiguration where every option can be toggled on or off. If no options object is passed, a default one will be used.
Cesium fixes / enhancements:
  • Fix entities shadowing bug - fixEntitiesShadows
Cesium configuration
In order to use cesium you must serve some assets from cesium package. The following configuration is for angular-cli projects, for webpack users try this.
  • install cesium via:
     $ npm install --save cesium
  • Add cesium assets, script and css in .angular-cli.json file:
     "assets": [ // ...
          { "glob": "**/*", "input": "../node_modules/cesium/Build/Cesium", "output": "./assets/cesium" }
        "styles": [ // ...
        "scripts": [ // ...
  • Add CESIUM_BASE_URL in main.ts file , before bootstraping:
      // ...
      window['CESIUM_BASE_URL'] = '/assets/cesium';
  • Add declare var Cesium; to typing.d.ts file.
  • You can configure cesium viewer style:
     // styles.css
    html, body, #cesiumContainer {
        width: 100%;
        height: 100%;
        margin: 0;
        padding: 0;
        overflow: hidden;
  • Live long and prosper


  • You can try and learn about angular-cesium from our demo: ( most optimized as desktop application ).
  • The demo contains 2 examples
    • Real data: showing real planes using GraphQL to warp an exiting REST service.
    • Simulated data: displaying planes data and sending using
        $ git clone
      $ cd angular-cesium
      $ yarn
      $ yarn server
      $ yarn start
      $ open http://localhost:8080

Basic example

  • In your HTML file :
        <ac-layer acFor="let plane of planes$" [show]="showTracks" [context]="this">  
          <ac-billboard-desc props="{  
               image: plane.image,  
               position: plane.position  
          <ac-label-desc props="{  
              position: plane.position,  

  • ac-map creates the map
  • ac-layer component represent an array of entities that will be displayed on the map.
    • acFor attribute accepts an RxObserver planes$ , ac-layer will subscribe to the observer and will handle all updates for you.
  • Add descriptions components to determine which entity to render, in our example: ac-billboard and ac-label .
    • This example will render a billboard(icon) and label for each plane in the stream.
    • props accepts the same member options as cesium corresponding class. For example ac-billborad-desc accepts same members as cesium Billboard.

AC Layer

ac-layer is a directive which is meant to define a whole layer. In case you have previous knowledge about CesiumJs, you would notice that there are lots of map objects e.g. billboard, label, etc'. In the real world - we would like to merge all of this map objects into a single entity e.g. an airplane consists of a billboard(icon) and a label. Now, let's create a simple airplanes layer and go through it's definitions: First of all - the data source for a layer must be an RxJs stream. Second - every notification on the stream should be of type AcNotification:
 export class AcNotification {  
      id: number;  
      entity?: AcEntity;  
      actionType: ActionType;  
id - unique entity key, entity- the data itself for the entity, actionType- presents what happened to the entity. actionType can be one of those values:
 export enum ActionType {  
In case ADD_UPDATE is passed - the entity will be created or updated depending on if it exists or not. In case DELETE is passed - the entity will be removed from the map.
Now, assuming that each entity on this stream presents a plane, lets assume that each plane consists of this schema:
  • position - which presents the current plan position
  • name - which presents the plane name(to be presented on the map).
  • image - the PNG or whatever image you may like to use.
Now, Let's look at this piece of code:
    <ac-layer acFor="let plane of planes$" [context]="this" [store]="true">  
      <ac-billboard-desc props="{  
           image: plane.image,  
           position: plane.position  
      <ac-label-desc props="{  
          position: plane.position,  
          fillColor: getColor(plane)  
  • ac-map - Is a directive which presents the map and create a new Cesium instance.
  • ac-layer - Is our current directive which presents a plan layer. Remember that the data source must be a stream? In our case the stream is planes$.
  • acFor - Is a directive which lets you decide how would you call a single plane(or a single entity on the stream) in order to write the relevant expressions inside the directive(we'll see this in a moment). It should be noticed that the format for acFor is: let {x} of {our stream}.
  • context - The context of the observable (planes$) and the cesium descriptions props (same context as getColor). Usually it will be the context of the component itself - this.
  • store - Default: false. Tells Ac-Layer if it should store the entities it receives. The entities stored in the Ac-Layer store are extends by notifications from the stream (planes$).The store is an <entity id, entity> map. This in an optional basic data store. You can you use any kind of third party data store (e.g. ngrx/store).
Now, after we have defined our layer and decided that each entity on the stream will be called plane, let's drill down into the definitions of how an entity should look.
  • ac-billboard-desc - which presents billboard from CesiumJs. This directive allows you to pass props(expressions) to this billboard. You may see that although we do pass props - we actually pass expressions that are based on the plane that we defined earlier. Actually we say: 'Dear angular-cesium, please create and manage a billboard using those expressions for each plane'. Now, when an entity is passed through the stream - based on it's id, actionType and entity - angular-cesium will know what to do. When passing data with the same id and actionType=ADD_UPDATE - the entity will be updated on the map for every message.
  • ac-label-desc - the same as ac-billboard-desc but just for labels. It should be mentioned that ac-billboard-desc & ac-label-desc are all exposing the same API as Cesium expose for each map-entity.
It is important to mention that angular-cesium doesn't duplicate the description component over the DOM for each different plane in $plane (as ngFor does).

why? because there is no reason to, cesium entities are drawn on the canvas map using javascript API i.e. entities aren't represented as HTML, by doing so we gain a major boost in performance.
After explaining a little bit about ac-layer we hope that you may see it's benefits:
  • Easily defining a layer
  • Easily add/update/remove entities - all you have to do is pass a message through the stream and angular-cesium will keep track of all the rest.
  • Readable code - when reading your html which describes your layer - it is pretty easy to understand how your layer would look.
  • Maintainable code.

Supported Entity types

ac-entity-desc vs ac-entity

  • ac-entity-desc component is used to describe how each entity / array of entities in a stream of entities, managed inside ac-layer, should be drawn.
  • ac-entity-primitive-desc component is the same as ac-entity-desc with the difference of using Primitives to render the graphics. It is more efficient than ac-entity-desc when drawing an updating entity.
  • ac-entity component is used to draw an entity directly on the map, and so, can be used directly under ac-map.

Entities API

  • All of the entity components are using a flatten Cesium Entities API.
  • e.g: ac-billboard props input accepts a JSON which can have all properties found in Cesium Entity (like position) plus all properties found in Cesium BillboardGraphics (like).
  • In AngularCesium, entities have a default height of 0 (except of Billboards and Labels). This as in line with Cesium docs. For some reason in Cesium itself, the default height is undefined which leads Cesium to use GroundPrimitive which is less efficient. As a result, if you want your entity to be more efficient, set height: 0 or any other value in the props.

Map Events

MapEventsManagerService is a util service for managing all the map events (Click, Mouse_up...), it expose easy API for entity selection, event priority management and adds custom events (drag and drop, long press).
 export class SomeComponent{  
  constructor(private eventManager: MapEventsManagerService){  
   // Input about the wanted event   
   const eventRegistration: EventRegistrationInput = {  
    event: CesiumEvent.LEFT_CLICK, // event type enum. [required!]  
    modifier: CesiumEventModifier.CTRL, // event modifier enum. [optional]  
    entityType: AcEntity, // raise event only if AcEntity is clicked. [optional]   
    priority: 0, // event priority, default 0 . [optional]  
    pick: PickOptions.PICK_FIRST // entity pick option, default PickOptions.NO_PICK. [optional]  
   const clickEvent = this.eventManager.register(eventRegistration).subscribe((result) => {  
      // The EventResult will contain:   
      // movement(screen location of the event), entities(your entities) , primitives( cesium primitives, like label,billboard...)  
         console.log('map click', result.movement, 'primitives:', result.primitives, 'entities', result.entities);  
In the example above we start listing to Click events. according to eventRegisration object.
  • eventManager.register()
    • Returns RxJs observer of type DisposableObservable<EventResult> that we can subsribe to.
    • To remove the event registration just do: resultObserver.dispose()
  • event: according to CesiumEvent enum. All cesium events are supported, includes additional events like DragNDrop and LongPress
  • entityType: it is possible to register to events on a specific entities types, e.g raise event only when TrackEntity is Clicked.
    • AcEntity is the base class for all angular-cesium entities, it is a part of AcNotification and is required for MapEventManager to work properly.
    • All entities should inherit from AcEntity
      e.g class TrackEntity extends AcEntity {}
  • Priority: by setting the priority you can register same events and only the one with the higher priority will be raised. For example lets say when you left_click on the map a context menu should appear but if you in a drag and drop state you want that left_click will raise a drop event only, you can achive this by setting different priority to each event.
  • PickOptions: according to the PickOptions enum, set the different strategies for picking entities on the map:
    • NO_PICK - will not pick entities
    • PICK_FIRST - first entity will be picked . use Cesium.scene.pick()
    • PICK_ONE - in case a few entities are picked plonter is resolved . use Cesium.scene.drillPick()
    • PICK_ALL - all entities are picked. use Cesium.scene.drillPick()
MapEventsManagerService is porivided by <ac-map/>, therefor has 2 possibilitis to reach it:
  • In any components under <ac-map/> hierarchy as seen in the example above (recomannded).
  • Using@viewChild and ac-map reference: acMapComponent.getMapEventManagerService() .
Checkout demo/app/components/event-test-layer/event-test-layer.component.ts for more examples.
All cesium map events run out side angular zone
Meaning that the the callback that you pass to map event manager will be executed outside of angular zone. That is because Cesium run outside of Angular zone in case for performance reasons , kind of ON_PUSH strategy.
For example if you update your html template for every map event and you want it to render, you should use ChangeDetectorRef or warp your function with
 class MyComponent {  
  constructor(eventManager: MapEventsManagerService, ngZone: NgZone){  
    eventManager.register(eventRegistration).subscribe((result) => {>{  
        this.textShownInTheTemplateHtml = result.movment;  


In case a two or more entities are in the same location and both are clicked you have a plonter (which entity should be picked?).
This is resolved according to the PickOptions that we pass to the event registration:
  • NO_PICK - non of the entities will be picked, you only interested in the map location.
  • PICK_FIRST - the first(upper) entity will be picked.
  • PICK_ALL - all entities are picked and returned.
  • PICK_ONE - only one should be picked, a context will appear allowing the client to choose which entity he wants, selected entity will be passed to the eventcall back.
angular-cesium comes with ac-default-plonter a basic implementation for the plonter context menu. showing a list of entities names to select from.
It is possible to create your own plonter context menu just take a look at ac-default-plonter implementation, and disable the default plonter:
 <ac-map [disableDefaultPlonter]="true"></ac-map>  

Map layers

With angular cesium you can define your map provider in a declarative way using ac-map-layer-provider :
  <ac-map-layer-provider *ngIf="appSettingsService.showMapLayer" [provider]="MapLayerProviderOptions.ArcGisMapServer"  
                 url : ''  
  • All cesium imagery map layers are supported , defined with [provider] according to the MapLayerProviderOptions enum
  • Pass additional configuration to [options] . url is mandatory.
  • Support multi map layers, map ordering and map image layer configuration.
  • Check out usage example from our demo here

3d Tiles

      url: ''  

Camera Keyboard Control Service

    W: { action: KeyboardAction.CAMERA_FORWARD },  
    S: { action: KeyboardAction.CAMERA_BACKWARD },  
    D: { action: KeyboardAction.CAMERA_RIGHT },  
    A: { action: KeyboardAction.CAMERA_LEFT },  


Angular Cesium extends cesium api and expose additional features, but if you want to use pure cesium api you can use MapsManagerService to receive cesium viewer or any other util service that was created by ac-map.
 class MyComp {  
 constructor(mapsManagerService: MapsManagerService)  
      const viewer = mapsManagerService.getMap().getCesiumViewer();  
      const mapEventManager = mapsManagerService.getMap().getMapEventsManager();  
      const cameraService = mapsManagerService.getMap().getCameraService();  

Geometry Editors

Part of AngularCesiumWidgetsModule are useful geometry editors tool:
Try running our demo for examples (uncomment the relevant components in demo-map.component.html).


Check out our api Docs
Note: Special thanks to TGFTech
Disclaimer: The blog is created to share angular directives information to geek, curious Angular Developers.


December 23, 2017
Wrapper around sessionStorage, localStorage and cookies for angular. If both are unavailable will use an in memory storage.
Expiry is also implemented for all drivers not just cookies

Getting Started

$ npm i --save angular-safeguard

import {NgModule} from '@angular/core'
import {LockerModule, Locker, DRIVERS} from 'angular-safeguard'

  selector: 'app',
  template: `...`
class App {
  constructor(locker: Locker) {
    locker.set(DRIVERS.SESSION, 'something', value)

  imports: [LockerModule],
  declarations: [App],
  bootstrap: [App]
class AppModule {
  constructor(private locker: Locker) {}

With Custom Config

import {LockerModule, LockerConfig, DRIVERS} from 'angular-safeguard'

// to set a single driver
const lockerConfig = {
  driverNamespace: 'nameSpace',
  driverFallback: DRIVERS.MEMORY,
  namespaceSeperator: '-'

// to set fallback drivers in order of preference, pass in an Array of Driver
const lockerConfig = {
  driverNamespace: 'nameSpace',
  namespaceSeperator: '-'

  imports: [LockerModule.withConfig(lockerConfig)]
class SomeModule {



locker.get(DRIVERS.SESSION, 'myKey')
locker.set(DRIVERS.SESSION, 'myKey', 'value')
locker.set(DRIVERS.SESSION, 'myKey', {object: 'value'})

const expiry = new Date()

expiry.setHours(expiry.getHours() + 1)

locker.set(DRIVERS.SESSION, 'myKey', 'value', {expiry}) // will work with every driver type

// You can also use set to pass options for cookies like maxAge and such
locker.set(DRIVERS.COOKIES, 'key', 'value')

locker.key(DRIVERS.COOKIES, 0) // 'key'
locker.has(DRIVERS.LOCAL, 'key')
locker.setNamespace() // Resets to lockerConfig default
locker.setSeparator() // Resets to lockerConfig default
locker.remove(DRIVERS.SESSION, 'key')

Static Methods


These are the types of drivers available. If you try to set it to a (single) driver that is unsupported it will fallback to the memory driver. To set fallback drivers, pass in an Array of drivers in the order or preference:
Again, if every driver in Array is unsupported, it will fall back to memory driver.
Types are available from import {DRIVERS} from 'angular-safeguard'
  • DRIVERS.SESSION - Session Cache
  • DRIVERS.LOCAL - Local Storage
  • DRIVERS.MEMORY - Memory Storage
  • DRIVERS.COOKIE - Cookies


Why is my data getting set to {data: myDataHere} instead of just myDataHere?: angular-safeguard provides expiry on more than just cookies, to do this it's necessary to create a bit of a more complex object so we can store expiry and more.
Note: Special thanks to Mika Kalathil
Disclaimer: The blog is created to share angular directives information to geek, curious Angular Developers.


December 22, 2017
This library contains native Angular components and directives written from scratch in TypeScript using the Lightning Design System CSS framework. We are looking for community help to find and fix bugs, improve demo site and create new components.



Install through npm:
 npm install --save ng-lightning
If you use SystemJS to load your files, you should adjust your configuration to point our UMD bundle through unpkg
 map: {
  'ng-lightning/ng-lightning': ''


This library depends on Salesforce's LDS markup and CSS (tested with 2.2.1). We don't ship any CSS file, but you have to take care of including LDS CSS rules in your page. There are various ways to achieve this, for example compiling through their source files (@salesforce-ux/design-system) or by adding this into your

SVG Icons

Because of various cross-domain issues, if you want to use SLDS icons, you must provide a copy of the various sprite files (ie @salesforce-ux/design-system/assets/icons/action-sprite/svg/symbols.svg), served locally through your server. Check our webpack configuration, to see how we achieve this for our demo page.

IE11 support

Unfortunately, IE11 does not support two important features.
  • SVG External Content, used to load SVG icons from a spritemap. In order to support this, you will need to use a small script called svg4everybody.
    Available on npm cdn here.
  • Element.classList on SVG elements, used by Angular's renderer.setElementClass. See here for more information. Use classList.js shim, available on npm cdn here.
Typically, these shims should be placed within the <head> element.


Development is supported by ZuluTrade.


We support the same browsers and versions supported by both Angular and Salesforce's Lightning Design System. Cross browser/environment testing is performed through Saucelabs.
Note: Special thanks to ng-lightning
Disclaimer: The blog is created to share angular directives information to geek, curious Angular Developers.
ng2-table - Simple table extension with sorting, filtering, paging... for Angular2 apps

ng2-table - Simple table extension with sorting, filtering, paging... for Angular2 apps

December 21, 2017

Usage & Demo


  1. A recommended way to install ng2-table is through npm package manager using the following command:
     npm i ng2-table --save
    Alternatively, you can download it in a ZIP file
  2. More information regarding using of ng2-table is located in demo and demo sources.


Inputs (Properties)

  • page (number) - the default page after the table component loading
  • itemsPerPage (number) - number of the displaying items (rows) on a page
  • maxSize (number) - number of the displaying pages before ...
  • numPages (number) - total number of the pages
  • length (number) - total number of the items after filtering (of it's chosen)
  • config (?any) - config for setup all plugins (filtering, sorting, paging):
    • paging (?boolean) - - switch on the paging plugin
    • sorting (?any) - switch on the sorting plugin
      • columns (Array<any>) - only list of the columns for sorting
    • filtering (?any) - switch on the filtering plugin
      • filterString (string) - the default value for filter
      • columnName (string) - the property name in raw data
    • className (string|Array<string>) - additional CSS classes that should be added to a
    • rows (?Array<any>) - only list of the rows which should be displayed
    • columns (?Array<any>) - config for columns (+ sorting settings if it's needed)
      • title (string) - the title of column header
      • name (string) - the property name in data
      • sort (?string|boolean) - config for columns (+ sorting settings if it's needed), sorting is switched on by default for each column
      • className (string|Array<string>) - additional CSS classes that should be added to a column header
      • filtering (?any) - switch on the filtering plugin
        • filterString (string) - the default value for filter
        • columnName (string) - the property name in raw data

Outputs (Events)

  • tableChanged: data change event handler
  • cellClicked: onclick event handler


The responsibility of the filtering issue falls on user. You should choose on which columns the filter would be applied. You could add any number of different filters. Filter string - it's a string for matching values in raw data. Column name refers to the property name in raw data. The rest logic you could organize by yourself (the order of filters, data formats, etc). Even you could use filter for list of data columns.
You can also set up filtering param for columns, in this case filter box will appear in first row of the table.


Data sorting could be in 3 modes: asc, desc and without sorting data (as it comes from backend or somewhere else). If you want to switch off the sorting for some of the columns then you should set it forcibly in columns config (set property sort to false value for each column you want)


Pagination could be used from ng2-bootstrap - pagination component. When the page is changed, the pagination component will emit event change-table with an object {page, itemsPerPage}. Then you can easily subscribe on it and request corresponding raw data.
Note: Special thanks to Valor Software
Disclaimer: The blog is created to share angular directives information to geek, curious Angular Developers.