14.0.4 • Published 2 years ago

ngx-feature-flag-router v14.0.4

Weekly downloads
-
License
MIT
Repository
github
Last release
2 years ago

NgxFeatureFlagRouter

GitHub package.json version GitHub npm npm Website Custom badge

Demo

Extends RouteModule functionality to allow for conditionally lazy-loading child routes based on feature flag. Allows for Services to configure Routes and includes helpers for preload strategy.

This allows you to use an endpoint to lazy-load modules, easily redirect users to 403/404 pages, performant A/B testing for features.

Angular Major Version Support

Angular VersionSupport
9✅ Yes
10✅ Yes
11✅ Yes
12✅ Yes
13✅ Yes
14Mostly. Support for loadComponent coming soon

Installation

Add:

ng add ngx-feature-flag-router

Update:

ng update ngx-feature-flag-router #Updates ngx-feature-flag-router to latest version

If you're not using the latest version of Angular, you'll have to specify the major version:

ng update ngx-feature-flag-router@10 #Specific to Angular 10

How to Use

  1. Replace RouterModule.forChild() with FeatureFlagRouterModule.forChild()

Before:

import { RouterModule, Routes } from '@angular/router';

const routes: Routes = [
    /*...*/
];

@NgModule({
    imports: [RouterModule.forChild(routes)],
})
export class MyModule {}

After:

import { FeatureFlagRouterModule, FeatureFlagRoutes } from 'ngx-feature-flag-router';

const routes: FeatureFlagRoutes = [
    /*...*/
];

@NgModule({
    imports: [FeatureFlagRouterModule.forChild(routes)],
})
export class MyModule {}
  1. Add alternativeLoadChildren and featureFlag to conditional lazy-load alternative module when featureFlag returns true

Before:

const routes: Routes = [
    {
        path: 'hello-world',
        loadChildren: () => import('./hello-world.module').then((m) => m.HelloWorldModule),
    },
];

After:

const routes: FeatureFlagRoutes = [
    {
        path: 'hello-world',
        loadChildren: () => import('./hello-world.module').then((m) => m.HelloWorldModule),
        alternativeLoadChildren: () => import('./feature.module').then((m) => m.FeatureModule),
        featureFlag: () => showFeature(), // Function that returns boolean
    },
];

How to Use Services / API

  1. Add your Service ( MyService ) as the second argument of FeatureFlagRouterModule.forChild()
import { FeatureFlagRouterModule, FeatureFlagRoutes } from 'ngx-feature-flag-router';

// Initialize routes that don't require Service
const routes: FeatureFlagRoutes = [
    /*...*/
];

@NgModule({
    imports: [FeatureFlagRouterModule.forChild(routes, MyService)],
})
export class MyModule {}
  1. Add implements FeatureFlagRoutesService to your Service.
@Injectable({ providedIn: 'root' })
export class FeatureFlagService implements FeatureFlagRoutesService {
    // ...
}
  1. Add getFeatureRoutes() method and return your FeatureFlagRoutes
@Injectable({ providedIn: 'root' })
export class FeatureFlagService implements FeatureFlagRoutesService {
    // Get current user id
    private readonly userId$: Observable<number> = this.getUserId();

    constructor(private readonly httpClient: HttpClient) {}

    /** Set additional routes using Service */
    getFeatureRoutes(): FeatureFlagRoutes {
        return [
            {
                path: 'api-example',
                loadChildren: () => import('api-feature-flag-off.module').then((m) => m.ApiFeatureFlagOffModule),
                alternativeLoadChildren: () => import('api-feature-flag-on.module').then((m) => m.ApiFeatureFlagOnModule),
                featureFlag: () => this.showFeature(), // Function that returns Observable<boolean>
            },
        ];
    }

    /** Determine showing feature based on user id and API response */
    showFeature(): Observable<boolean> {
        // Use current user id
        return this.userId$.pipe(
            switchMap((userId) => {
                // Make specific request for that user
                return this.httpClient.get<UserStatus>('some/api');
            }),
            map((userStatus) => {
                // Check if we want to turn feature flag on or not
                return userStatus.authorized;
            }),
            // Replay results until user id changes if you only want to make the api request once
            shareReplay({ bufferSize: 1, refCount: true }),
        );
    }
}

Mono Repo

Demo and library is managed using Nx.

Contributing

Before adding any new feature or a fix, make sure to open an issue first :)

  1. Make sure to use the expected node/npm versions
node -v # v14.17.1
npm -v # 6.14.13

If you have the wrong versions, I suggest using nvm or volta for node version management.

  1. Clone the project and install dependencies
git clone https://github.com/m-thompson-code/ngx-feature-flag-router.git
npm install
  1. Create a new branch
git checkout -b feature/some-feature
  1. Add tests and make sure demo and library jest / cypress tests pass
npm run test # both demo and ngx-feature-flag-router lib

or

npm run test:demo # only demo
npm run test:lib # only ngx-feature-flag-router lib

You can also run jest tests separately

npm run jest:demo # only demo jest tests
npm run jest:lib # only ngx-feature-flag-router lib jest tests

and cypress tests separately

npm run e2e:demo # only demo cypress tests
npm run e2e:lib # only ngx-feature-flag-router lib cypress tests
  1. commit > push > create a pull request 🚀
9.0.4

2 years ago

9.0.3

2 years ago

10.0.2

2 years ago

10.0.3

2 years ago

10.0.4

2 years ago

13.0.4

2 years ago

13.0.2

2 years ago

13.0.3

2 years ago

14.0.3

2 years ago

14.0.4

2 years ago

12.0.3

2 years ago

12.0.4

2 years ago

12.0.2

2 years ago

11.0.4

2 years ago

9.0.2

2 years ago

11.0.2

2 years ago

11.0.3

2 years ago

12.0.0

2 years ago

12.0.1

2 years ago

10.0.0

2 years ago

10.0.1

2 years ago

13.0.0

2 years ago

9.0.1

2 years ago

13.0.1

2 years ago

9.0.0

2 years ago

11.0.0

2 years ago

11.0.1

2 years ago

0.1.1

2 years ago

0.2.0

2 years ago