@daysmart/angular-launch-darkly-service
TypeScript icon, indicating that this package has built-in type declarations

0.2.1 • Public • Published

npm downloads npm bundle size (minified + gzip)

Setup

Step 1 - Import the LaunchDarklyModule

Add the LaunchDarklyModule to your AppModule in order to start accessing your feature flags. You will need to provide your Launch Darkly API key in the forRoot module function. This should ONLY be imported into the AppModule and nowhere else. It is meant to be used by your entire application. If it's imported into more than one location, you will create multiple instances of the service it contains.

...
import { LaunchDarklyModule } from '@daysmart/angular-launch-darkly-service';
...

@NgModule({
  declarations: [
    SomeComponent
  ],
  imports: [
    ...
    LaunchDarklyModule.forRoot({ apiKey: environment.launchdarklyApiKey }),
    ...
  ],
  providers: []
})
export class AppModule {}

Step 2 - Set the current user's data once it's known

When your Angular page first loads, the LaunchDarkly user initialized will be an anonymous user with a key of anonymous_user. While linked with the anonymous user, all feature flags will be returned as false. Once you know the current user's actual identity, the LaunchDarklyService.setUser should be called.

setUser is deprecated use setContext instead. I suggest calling setUser from your top-most app guard if you have one so that all guards that run after it will be able to check feature flags reliably. If you do it elsewhere (even the AppComponent), the guards may run first and not get accurate flag information. The AppComponent does run ngOnInit in parallel with the guards running, so you won't be able to reliably check flags in your AppComponent. You might be able to duplicate the setUser call into your AppComponent too to get around this, just make sure to check what user is already set by calling getUser prior to setting it so that you are re-setting it over and over.

setUser takes in an LDUser specified here: https://launchdarkly.github.io/js-client-sdk/interfaces/_launchdarkly_js_client_sdk_.lduser.html

export class CanActivateAppGuard implements CanActivate {
    constructor(private launchDarklyService: LaunchDarklyService) {}
    async canActivate(
        next: ActivatedRouteSnapshot,
        state: RouterStateSnapshot
    ):
        | Observable<boolean | UrlTree>
        | Promise<boolean | UrlTree>
        | boolean
        | UrlTree {
        const existingLDUser: LDUser = this.launchDarklyService.getUser();

        if (
            result.data.webAccountInfo?.customerID > 0 &&
            (!existingLDUser ||
                existingLDUser.key !== result.data.webAccountInfo.customerID)
        ) {
            await this.launchDarklyService.setUser({
                key: result.data.webAccountInfo.customerID,
            });
        }

        if (someReasonToRedirect) {
            return this.router.parseUrl('/not_found');
        } else {
            return true;
        }
    }
}

Step 3 - Prevent the service from breaking your tests

Import the LaunchDarklyMockModule into the test module that tests whatever object you added the service to in the previous step. See the Testing section further down for more information.

Usage

Add the LaunchDarklyService to any component/directive/guard/etc. you'd like to have check a feature, call isFeatureActive and pass in the feature key associated with the flag.

Example

export class SomeComponent {
    constructor(private launchDarklyService: LaunchDarklyService) {}

    isMyAwesomeNewFeatureActive(): boolean {
        return this.launchDarklyService.isFeatureActive(
            'awesome_new_feature_key'
        );
    }
}
<div class="some-stuff">
    <div class="existing-stuff">...</div>
    <div class="awesome-new-stuff" *ngIf="isMyAwesomeNewFeatureActive()">
        ...
    </div>
</div>

Testing

You will need to import the LaunchDarklyMockModule into any test modules that will be testing an object that has the LaunchDarklyService in its constructor. Without doing this, your tests will try to make calls to LaunchDarkly over the internet and fail.

Example

describe('AppComponent', () => {
    let component: AppComponent;
    let fixture: ComponentFixture<AppComponent>;

    beforeEach(async () => {
        await TestBed.configureTestingModule({
            declarations: [AppComponent],
            imports: [
                ...
                LaunchDarklyMockModule,
                ...
            ],
        }).compileComponents();
    });

    beforeEach(() => {
        fixture = TestBed.createComponent(AppComponent);
        component = fixture.componentInstance;
        fixture.detectChanges();
    });

    it('should create', () => {
        expect(component).toBeTruthy();
    });
});

Readme

Keywords

none

Package Sidebar

Install

npm i @daysmart/angular-launch-darkly-service

Weekly Downloads

166

Version

0.2.1

License

none

Unpacked Size

138 kB

Total Files

21

Last publish

Collaborators

  • automaticgiant
  • d.lindstrom
  • jordanrickmandaysmart
  • devendra.deshmukh
  • shafik23
  • aclebert
  • mohammed.radhi
  • pavitra.srinivasan
  • wmcintyre
  • mberryman_daysmart
  • daysmartgithubactions
  • taylorgarpow
  • daysmartadmin
  • nthornton2010
  • shereefz
  • jenelle.farris