angular-feature-toggle

0.1.6 • Public • Published

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)

Readme

Keywords

Package Sidebar

Install

npm i angular-feature-toggle

Weekly Downloads

885

Version

0.1.6

License

ISC

Last publish

Collaborators

  • yairhaimo