npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@daysmart/angular-launch-darkly-service

v0.2.1

Published

[![npm downloads](https://img.shields.io/npm/dm/@daysmart/angular-launch-darkly-service.svg)](https://npmjs.org/@daysmart/angular-launch-darkly-service) [![npm bundle size (minified + gzip)](https://img.shields.io/bundlephobia/minzip/@daysmart/angular-la

Downloads

52

Readme

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();
    });
});