angular-feature-toggle

feature toggling capabilities for angular

Downloads in past

Stats

StarsIssuesVersionUpdatedCreatedSize
angular-feature-toggle
0.1.69 years ago9 years agoMinified + gzip package size for angular-feature-toggle in KB

Readme

npm version
angular-feature-toggle

Synopsis

This library lets you manage features in the frontend using a semver notation.
Inspired by angular-feature-flags.

Examples and Demo

Check out the example directory for a simple usage of the library or this plunker for the same demo.

Installation

npm install angular-feature-toggle --save
angular.module('main.app', ['yh.featureToggle'])

Configuration

angular-feature-toggle uses a semver notation per feature and expects a configuration of this nature:
{
    "feature1": "1.5.1",
    "feature2": "0.5.6"
}
This configuration toggles features inside the code according to their version conditions.
//Example for "feature1" : "1.5.1"
//^1.0.0 - true
//~1.5.0 - true
//~1.6.0 - false
//^2 - false
//* - true
For more information regarding the semver notation head over to the semver and the node-semver sites.
NOTE: In order to configure itself at angular's config phase angular-feature-toggle is, at the moment, dependant on a property named 'angularFeaturesConf' on the global window object.
Manual setting
For hardcoded values you can set the property manually:
window.angularFeaturesConf = {dashboard: '1.0.0', admin: '0.5.1'};
For a dynamic feature loading method take a look at the serverside feature loading example.

ui.router

angular-feature-toggle detects if ui.router is in use and wraps it with a feature-toggle helper function.
You can now define your states this way:
$stateProvider
  .state('master.dashboard',
     {
       url: '/dashboard',
       templateUrl: 'dashboard/dashboard.html',
       controller: 'DashboardController',
       controllerAs: 'dashboard',
       feature: 'dash', //optional
       version: '^0.5.1'
     }
   )
   .state('master.dashboard',
     {
       url: '/dashboard',
       templateUrl: 'NEWdashboard/newDashboard.html',
       controller: 'NewDashboardController',
       controllerAs: 'dashboard',
       feature: 'dash', //optional
       version: '^1'
     }
   );
Note that both states have the same name but different version conditions (^0.5.1 vs ^1).
If the version is not satisfied for a specific state definition then that definition will be ignored.
If more than one version of the same state is satisfied the first one will be defined and a warning message will be logged for the following ones.
The 'feature' property is optional, if omitted the state name is considered to be the feature name.
NOTE: if you omit the version parameter in the state definition then a regular state will be defined.

Toggle features using a directive

There are two directives you can use in order to toggle features: show-if-feature and hide-if-feature.
Basically they act as ng-if and the opposite of ng-if. They add/remove elements from the DOM if a feature is enabled or satisfies a certain version.
<div show-if-feature="admin">
    This is the admin panel
</div>
With a specific version:
<!-- will be shown if the admin feature exists and satisfies the version ^1 -->
<div show-if-feature="admin ^1">
    This is the admin panel
</div>
<!-- will be shown if the admin feature exists and satisfies the version ~2.0.1 -->
<div show-if-feature="admin ~2.0.1">
    This is the NEW and improved admin panel
</div>
<!-- will not be shown if the widget feature is enabled -->
<div hide-if-feature="widgets">
    Widgets coming soon...
</div>

Toggle features programmatically

You can use the featureToggle factory to check feature version:
.controller('HomeController', function(featureToggle) {
    if (featureToggle.isEnabled('admin')) {
        this.message = 'welcome administrator!';
    }
    if (featureToggle.isVersion('admin', '^2')) {
        this.items = [1,2,3];
    }
});
The featureToggle is also a provider and can be used inside .config blocks:
.config(function(featureToggleProvider) {
    if (featureToggleProvider.isVersion('dashboard', '~3.5.0')) {
        // do something
    }
});
NOTE: since angular-feature-toggle configures itself in a .config block it must be defined as a module dependancy in order for its .config block to run prior to the one that is using it.

Serverside feature configuration loading

Since we intialize the feature configuration in a .config block (in order to support state versioning) we cannot use the $http service to load the feature configuration from the server ($http is not injectable into a config block). What we can do is first load the configuration with vanilla javascript and only once its loaded manually bootstrap the angular applcation:
angular.element(document).ready(function() {
  fetch('/example/features.json').then(function(response) {
    response.json().then(function(features) {
      window.angularFeaturesConf = features;
      angular.bootstrap(document, ['app']);
    })
  });
});
This example uses the new fetch
API for brevity but you can use any ajax function you wish.

Limitations and TODOs

  • Dependency on a global window property - angularFeaturesConf
  • Cannot load feature configuration for a specific user since the feature initialization is done in the config phase
  • Reduce library size (uses the entire node-semver library atm, need only a subset of that)