@nickroberts/ng-feature-flags

Angular Feature Flags

Stats

stars 🌟issues ⚠️updated 🛠created 🐣size 🏋️‍♀️
00Oct 25, 2018Feb 15, 2018Minified + gzip package size for @nickroberts/ng-feature-flags in KB

Readme

NgFeatureFlags

Add the ability to turn features on and off through the use of feature flags.

Requirements

Installation

npm i @nickroberts/ng-feature-flags

Feature Flags JSON

Add a file to the public path assets/json/feature-flags.json. This is the default path where the loadRemoteConfig() function looks for the feature flag data:

[
  {
    "key": "feature-flag-one",
    "title": "Feature Flag One",
    "description": "This is a description of the feature flag.",
    "default": true
  },
  {
    "key": "feature-flag-two",
    "title": "Feature Flag Two",
    "description": "This is a description of the feature flag.",
    "default": false
  }
]

Module

Setup your default app.module by adding the NgffModule and loading the data before the app starts:

// app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule, APP_INITIALIZER } from '@angular/core';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { NgffModule, NgffProviderService } from '@nickroberts/ng-feature-flags';

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

export function setupNgff(ngffProviderService: NgffProviderService) {
  return () => ngffProviderService.loadRemoteData();
}

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule
    NgbModule.forRoot(),
    NgffModule
  ],
  providers: [
    NgffProviderService,
    {
      provide: APP_INITIALIZER,
      useFactory: setupNgff,
      deps: [NgffProviderService],
      multi: true
    }
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}

Custom Feature Flag JSON

You can setup a custom url when loading the json file if you do not want to use the default location:

// app.module.ts

export function setupNgff(ngffProviderService: NgffProviderService) {
  const url = 'https://url-for-feature-flags-json';
  return () => ngffProviderService.loadRemoteData(url);
}

Loading Feature Flag Data From Angular's Environment

You can also load feaure flag data from Angular's environment files:

// environment.ts

export const environment = {
  production: false,
  featureFlags: [
    {
      key: 'environment-cool-new-feature',
      title: 'Environment Cool New Feature',
      description: 'This is loaded from the Angular environment.',
      default: false
    }
  ]
};
// app.module.ts

import { environment } from '../environments/environment';

export function setupNgff() {
  return () => ngffProviderService.init(environment.featureFlags);
}

Combining Remote JSON and Environment Data

You can also include both remote and local data:

// app.module.ts

export function setupNgff(http: HttpClient, ngffProviderService: NgffProviderService) {
  const url = 'https://url-for-feature-flags-json';
  return () => http
    .get<NgffFeatureFlagData[]>(url)
    .take(1)
    .map(data => {
      if (environment.featureFlags) {
        return <NgffFeatureFlagData[]>[ ...data, ...environment.featureFlags ];
      }
      return data;
    })
    .switchMap(data => ngffProviderService.init(data).take(1))
    .toPromise();
}

Usage

Components

To show the list of feature flags, where you can enable and disable them:

<ngff-list></ngff-list>

Directive

You can use the *ngffIf="['feature-flag-name']" directive to show or hide an element based on a feature flag.

To show an element when a feature flag is on:

<div *ngffIf="['cool-new-feature']">
  I only show when the "cool-new-feature" feature flag is turned "on".
</div>

Tp hide an element when a feature flag is on:

<div *ngffIf="['cool-new-feature']; hide: true;">
  I only show when the "cool-new-feature" feature flag is turned "off".
</div>

To show an element when multiple feature flags are on:

<div *ngffIf="['cool-new-feature', 'another-cool-new-feature']">
  I only show when both the "cool-new-feature" and "another-cool-new-feature" feature flags are turned "on".
</div>

To show an element when one of multiple feature flags are on:

<div *ngffIf="['cool-new-feature', 'another-cool-new-feature']; operator: 'OR';">
  I show when either the "cool-new-feature" or "another-cool-new-feature" feature flag are turned "on".
</div>

Note: you cannot use other template referral directives when using this, e.g. *ngIf="true".

Service

Provide the service to your module:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { NgffDataService } from '@nickroberts/ng-feature-flags';

@NgModule({
  imports: [CommonModule],
  providers: [NgffDataService]
})
export class SharedModule {}

Inject the service into your component:

import { Component } from '@angular/core';
import { NgffDataService } from '@nickroberts/ng-feature-flags';

@Component({
  selector: 'app-root',
  template: `
    <pre>{{ flag }}: {{ enabled }}
  `,
  styles: []
})
export class AppComponent implements OnInit {

  flag = 'cool-new-feature';
  enabled: boolean;

  constructor(private ngffDataService: NgffDataService) { }

  ngOnInit() {
    this.enabled = this.ngffDataService.enabled(this.flag);
  }

}

If you find any bugs or have a feature request, please open an issue on github!

The npm package download data comes from npm's download counts api and package details come from npms.io.