• Stars
    star
    99
  • Rank 341,386 (Top 7 %)
  • Language
    TypeScript
  • License
    MIT License
  • Created over 7 years ago
  • Updated 3 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Your module to handle with feature toggles in Angular applications easier.

NGX Feature Toggle

Dependency Status npm

NPM NPM

Build Status Coverage Status npm bundle size (minified + gzip) npm

Your module to handle with feature toggles in Angular applications easier.

Why Feature toggle?

This is a common concept, but why use this directive instead solve it via server-side rendering?

The idea of this directive is make this process transparent and easier. So the main point is integrate this directive with other tooling process, such as:

  • Server-side rendering;
  • Progressive rendering;
  • Any other that you like :)

You can integrate with WebSockets or handling this in a EventSourcing architecture. It's totally transparent for you and you can integrate easier in your application.

Demo

Try out the demos on Stackblitz:

Install

You can get it on NPM installing ngx-feature-toggle module as a project dependency.

npm install ngx-feature-toggle --save

Setup

You'll need to add FeatureToggleModule to your application module. So that, the featureToggle components will be accessible in your application.

...
import { FeatureToggleModule } from 'ngx-feature-toggle';
...
@NgModule({
  declarations: [
    YourAppComponent
  ],
  imports: [
    ...
    FeatureToggleModule,
    ...
  ],
  providers: [],
  bootstrap: [YourAppComponent]
})

export class YourAppComponent {}

Now you just need to add a configuration in your application root component. Your feature toggle configuration can be added using different approaches, such as:

  • RXJS subscribe information;
  • HTTP Request;
  • CQRS event data;
  • File information;
  • etc;

After that, you can use the featureToggle components and directives in your templates, passing the string based on the feature toggle configuration data.

Module

Components and Directives

  • feature-toggle-provider: Handle with feature toggle configuration in your application. It adds the default values of your enabled/disabled features;
  • *featureToggle: Directive that handles with feature toggle check. So that, the component will be rendered/removed based on the feature toggle configuration is enabled;
  • *featureToggleWhenDisabled: Directive that handles with feature toggle check. So that, the component will be rendered/removed when the feature toggle configuration is disabled;
import { Component } from '@angular/core';

@Component({
  selector: 'component-docs',
  template: `
    <feature-toggle-provider [features]="featureToggleData">
      <div *featureToggle="'enableSecondText'">
        <p>condition is true and "featureToggle" is enabled.</p>
      </div>
      <div *featureToggle="'enableFirstText'">
        <p>condition is false and "featureToggle" is disabled. In that case this content should not be rendered.</p>
      </div>
      <div *featureToggle="'!enableFirstText'">
        <p>
          condition is false and "featureToggle" is disabled
          <b>but it has "!" as a prefix of the feature toggle to be checked.</b>
          In that case this content should be rendered.
        </p>
      </div>
      <div
        class="combined-feature-toggles-with-truthly-option"
        *featureToggle="['!enableFirstText', 'enableSecondText']"
      >
        <p>
          This is a combined condition. It shows if <b>enableSecondText</b> is true and <b>enableFirstText</b> is falsy,
          but it has "!" as a prefix. If both cases are correct, then the "featureToggle" is enabled and rendering this
          component.
        </p>
      </div>
    </feature-toggle-provider>
  `,
})
export class ComponentDocsComponent {
  public featureToggleData: any = {
    enableFirstText: false,
    enableSecondText: true,
  };
}

Route Guards

In some scenarios when you need to prevent the route to be loaded, you can use NgxFeatureToggleCanLoadGuard, by passing the class and configuration of the feature toggle to be checked in your route data.

...
export const routes: Routes = [

  {
    path: 'home',
    component: HomeComponent,
    canActivate: [NgxFeatureToggleCanLoadGuard],
    data: {
      // Using array as configuration
      featureToggle: [
        // This configuration will check if feature toggle is enabled
        'enableSecondText',
        // This configuration will check if feature toggle is disabled
        // since it has `!` prefix in the configuration
        '!enableFirstText'
      ],
    },
  },
  {
    path: 'dashboard',
    component: DashboardComponent,
    canActivate: [NgxFeatureToggleCanLoadGuard],
    data: {
      // Using string as configuration
      featureToggle: 'enableSecondText',
    },
  },
];
...

Also, you can use NgxFeatureToggleRouteGuard to check if the route should be activated or not by passing the class and configuration of the feature toggle to be checked in your route data.

...
export const routes: Routes = [

  {
    path: 'home',
    component: HomeComponent,
    canActivate: [NgxFeatureToggleRouteGuard],
    data: {
      // Using array as configuration
      featureToggle: [
        // This configuration will check if feature toggle is enabled
        'enableSecondText',
        // This configuration will check if feature toggle is disabled
        // since it has `!` prefix in the configuration
        '!enableFirstText'
      ],
    },
  },
  {
    path: 'dashboard',
    component: DashboardComponent,
    canActivate: [NgxFeatureToggleRouteGuard],
    data: {
      // Using string as configuration
      featureToggle: 'enableSecondText',
    },
  },
];
...

In both route guards you can pass route data with feature toggle as an array. For scenarios when you need to check for feature toggles enabled and/or disabled you can easily configure it by passing ! if the application should check if the feature toggle is disabled

...
export const routes: Routes = [
  {
    path: 'home',
    component: HomeComponent,
    canActivate: [NgxFeatureToggleRouteGuard],
    data: {
      // Using array as configuration
      featureToggle: [
        // This configuration will check if feature toggle is enabled
        'enableSecondText',
        // This configuration will check if feature toggle is disabled
        // since it has `!` prefix in the configuration
        '!enableFirstText'
      ],
    },
  },
  {
    path: 'dashboard',
    component: DashboardComponent,
    canActivate: [NgxFeatureToggleRouteGuard],
    data: {
      // Using string as configuration
      featureToggle: 'enableSecondText',
    },
  },
];
...

In this case, we are combining the checks. So the component will be activated if enableSecondText is configured as true AND enableFirstText is configured as false. With that configuration you can have all the flexibility to cover different scenarios in your app.

Use NgxFeatureToggleRouteGuard to control when the child component of a specific component can be activate via routing. It can be passed as an array of items.

...
export const routes: Routes = [
  {
    path: 'customer',
    component: CustomerComponent,
    canActivateChild: [NgxFeatureToggleRouteGuard],
    children: [
      {
        path: ':id',
        component: CustomerDetailComponent,
        // This is the featureToggle configuration for
        // the child component. It can also use
        // a combination of feature toggles
        data: {
          featureToggle: [
            // This configuration will check if feature toggle is enabled
            'enableCustomerPage',
            // This configuration will check if feature toggle is disabled
            // since it has `!` prefix in the configuration
            '!enableChildrenNavigation'],
        },
      },
    ],
  },
  {
    path: 'dashboard',
    component: DashboardComponent,
    canActivateChild: [NgxFeatureToggleRouteGuard],
    children: [
      {
        path: ':id',
        component: DashboardDetailsComponent,
        // This is the featureToggle configuration for
        // the child component. It can also use
        // a combination of feature toggles
        data: {
          // using string to configure
          featureToggle: 'enableDashboardDetailsPage',
        },
      },
    ],
  },
];
...

Redirects

You might have some specific requirements that you should redirect a user to a specific route in case of a feature flag is disabled. For that, you can use redirectTo as a mechanism to redirect a user in a specific route when it tries to access in a route with a CanActivate/CanActivateChild/CanLoad Feature Toggle Guard and the feature toggle is disabled.

For advanced scenarios you can use a combination of route guards AND redirects. E.G.

...
export const routes: Routes = [
  {
    path: 'customer',
    component: CustomerComponent,
    canLoad: [NgxFeatureToggleRouteGuard],
    canActivate: [NgxFeatureToggleRouteGuard],
    canActivateChild: [NgxFeatureToggleRouteGuard],
    // This is the featureToggle configuration for
    // the parent component
    data: {
      featureToggle: ['enableCustomerPage'],
      // If feature toggle is disabled, the user will be redirected to `/error` URL
      redirectTo: '/error'
    },
    children: [
      {
        path: ':id',
        component: CustomerDetailComponent,
        // This is the featureToggle configuration for
        // the child component. It can also use
        // a combination of feature toggles
        data: {
          featureToggle: ['enableCustomerPage', '!enableChildrenNavigation'],
          // If one (or all of them) of the feature toggle is disabled, the user will be redirected to `/customer-error` URL
          // Note that you can use redirects for the main url and their children
          redirectTo: '/customer-error'
        },
      },
    ],
  },
];
...

Development

Run demo locally

  1. This project uses Angular CLI as base. That means you just need to run npm start and access the link http://localhost:4200 in your browser

Run tests

  1. Run npm test for run tests. In case you want to test using watch, please use npm run tdd

Publish

this project is using np package to publish, which makes things straightforward. EX: np <patch|minor|major> --contents=dist/ngx-feature-toggle

For more details, please check np package on npmjs.com

Contribute

For any type of contribution, please follow the instructions in CONTRIBUTING.md and read CODE_OF_CONDUCT.md files.

Author

Wilson Mendes (willmendesneto)

More Repositories

1

ngx-skeleton-loader

Make beautiful, animated loading skeletons that automatically adapt to your Angular apps
TypeScript
560
star
2

micro-frontend-pages

Simulate a micro frontend project using NodeJS, React and NGinx Reverse Proxy in Alpine Docker images
JavaScript
183
star
3

keepr

JavaScript
103
star
4

build-checker-app

Application using ReactJS + NodeJS for to monitor build/deploy status in your Continuous Integration server
JavaScript
50
star
5

hyper-oh-my-zsh

Oh-My-ZSH theme based on hyper terminal default theme 😎
41
star
6

hex-to-css-filter

Easy way to generate colors from HEX to CSS Filters
TypeScript
37
star
7

perf-marks

The isomorphic, simplest, and lightweight solution for User Timing API in Javascript - 🚀 only 208B 🚀. Tree-shaking and entry points built-in. Simple as that!
TypeScript
36
star
8

react-sweet-wizard

Your module to handle with Form Wizards in ReactJS applications easier.
JavaScript
27
star
9

vagrant-frontend-mobile-box

Vagrant box for Ionic Developers
Shell
21
star
10

frontend-search

Shell
19
star
11

generator-reactor

Your generator for ReactJS apps
JavaScript
18
star
12

build-checker

Application using Arduino + Johnny Five + NodeJS for to monitor build/deploy status in your Continuos Integration server
JavaScript
18
star
13

angular-contact-list

JavaScript
16
star
14

vscode-file-extra

Working with files in VSCode like a boss 😎
TypeScript
15
star
15

ng-numbers-only

NG Numbers Only - Input number in a easy way in AngularJS Apps
JavaScript
15
star
16

nodebots-workshop

Nodebots Workshop using NodeJS and Johnny-five
JavaScript
15
star
17

ngOfflineModel

Your AngularJS Module for Offline operations
JavaScript
13
star
18

feature-toggle-service

The simplest solution for feature toggle in Javascript. Simple how it should be.
TypeScript
12
star
19

CI-Tools

A code generator console for Codeigniter Framework.
PHP
12
star
20

update-yeoman-generator

A script to help update repositories using Yeoman generators to the latest version
JavaScript
11
star
21

ngx-page-click

Angular module to detect page events outside your wrapped component. Flexible and easy, how it should be ⇢
TypeScript
11
star
22

angular-performance

JavaScript
10
star
23

ngx-copy-to-clipboard

Copy content to clipboard in Angular applications easier 🎯.
TypeScript
9
star
24

ngx-micro-frontend-pages

Angular Microfrontend workshop - A collection of Page Modules and Components
TypeScript
9
star
25

micro-frontend-react-pages

CSS
7
star
26

ngx-scroll-lock

Angular module for Page Scroll locking
HTML
6
star
27

reactor-feature-toggle

Feature toggle components integration for your ReactJS application
TypeScript
6
star
28

my-codeigniter-skeleton

My skeleton for application with Codeigniter PHP Framework
PHP
6
star
29

bolt-complete

Bolt command completion
JavaScript
6
star
30

angular-architecture

My architecture organization for use of AngularJS Framework
JavaScript
6
star
31

social-share

JavaScript
5
star
32

angular2-feature-toggle

Your module to handle with feature toggles in Angular2 applications easier.
JavaScript
4
star
33

willmendesneto.github.io

My personal blog
JavaScript
4
star
34

node-github-diff

Github diffs with Node style 😎
JavaScript
3
star
35

dotfiles

My OSX default configuration
Shell
3
star
36

gdg-devfest-nordeste-app

JavaScript
3
star
37

fire-alarm

A Nodebots fire alarm using NodeJS Johnny-five
JavaScript
3
star
38

pino-sanitize

PinoJS Transformer to sanitize output by removing sensitive information
JavaScript
3
star
39

aws-serverless-playground

JavaScript
3
star
40

johnny-five-from-scratch

A Introduction to Johnny-Five, the JavaScript Robotics programming framework.
JavaScript
3
star
41

generator-poi-boilerplate-demo

Demo React Component from POI boilerplate generator
JavaScript
2
star
42

bitbucket-amazing-monorepo

Improving Monorepo projects for Bitbucket users 😎
JavaScript
2
star
43

Codeigniter-TDD-with-Hooks

A codeigniter unit tests example using only hooks.
PHP
2
star
44

card

My NPM business card
JavaScript
1
star
45

nodebots-javascript-and-robotic-in-a-real-world-en

1
star
46

angular-snake

JavaScript
1
star
47

npm-package-aliases-playground

JavaScript
1
star
48

generator-poi

JavaScript
1
star
49

nodebots-javascript-and-robotic-in-a-real-world-pt-br

1
star
50

arduino-matrix-8x8

Studies based in arduino plataform
C++
1
star
51

vhost

Making virtual host maniputation tasks more easier
Shell
1
star
52

react-hcard-generator

Simple hCard generator using ReactJS
JavaScript
1
star