) {
// code that runs after flag values are successfully resolved from the provider
}
}
```
--------------------------------
### Custom Tracking Strategy
Source: https://github.com/open-feature/js-sdk/blob/main/packages/server/src/provider/multi-provider/README.md
Implement a custom tracking strategy to control which providers receive tracking calls. This example shows how to selectively track based on provider name or event type.
```typescript
import { FirstMatchStrategy, StrategyPerProviderContext } from '@openfeature/server-sdk';
class CustomTrackingStrategy extends FirstMatchStrategy {
override shouldTrackWithThisProvider(
strategyContext: StrategyPerProviderContext,
context: EvaluationContext,
trackingEventName: string,
trackingEventDetails: TrackingEventDetails,
): boolean {
// Only track with the primary provider
if (strategyContext.providerName === 'primary-provider') {
return true;
}
// Skip tracking for analytics events on backup providers
if (trackingEventName.startsWith('analytics.')) {
return false;
}
return super.shouldTrackWithThisProvider(strategyContext, context, trackingEventName, trackingEventDetails);
}
}
```
--------------------------------
### FeatureFlagService with Observables
Source: https://github.com/open-feature/js-sdk/blob/main/packages/angular/projects/angular-sdk/README.md
Access feature flags programmatically using `FeatureFlagService`. All methods return Observables that emit new values upon configuration or context changes. This example demonstrates fetching boolean, string, number, and object flags.
```typescript
import { Component, inject } from '@angular/core';
import { AsyncPipe } from '@angular/common';
import { FeatureFlagService } from '@openfeature/angular-sdk';
@Component({
selector: 'my-component',
standalone: true,
imports: [AsyncPipe],
template:ധ്യ
Feature is enabled! Reason: {{ (isFeatureEnabled$ | async)?.reason }}
Theme: {{ (currentTheme$ | async)?.value }}
Max items: {{ (maxItems$ | async)?.value }}
ധ്യ,
})
export class MyComponent {
private flagService = inject(FeatureFlagService);
// Boolean flag
isFeatureEnabled$ = this.flagService.getBooleanDetails('my-feature', false);
// String flag
currentTheme$ = this.flagService.getStringDetails('theme', 'light');
// Number flag
maxItems$ = this.flagService.getNumberDetails('max-items', 10);
// Object flag with type safety
config$ = this.flagService.getObjectDetails<{ timeout: number }>('api-config', { timeout: 5000 });
}
```
--------------------------------
### Registering Providers with Domains
Source: https://github.com/open-feature/js-sdk/blob/main/packages/server/README.md
Demonstrates how to register providers, including a default provider and domain-specific providers, and how to obtain clients bound to these providers.
```typescript
import { OpenFeature, TypedInMemoryProvider } from '@openfeature/server-sdk';
const myFlags = {
v2_enabled: {
variants: {
on: true,
off: false,
},
disabled: false,
defaultVariant: 'on',
},
} as const;
OpenFeature.setProvider(new TypedInMemoryProvider(myFlags));
OpenFeature.setProvider('my-domain', new TypedInMemoryProvider(someOtherFlags));
const clientWithDefault = OpenFeature.getClient();
const domainScopedClient = OpenFeature.getClient('my-domain');
```
--------------------------------
### Initialize and Use OpenFeature Web SDK
Source: https://github.com/open-feature/js-sdk/blob/main/packages/web/README.md
This snippet shows how to register a feature flag provider and create a client to evaluate boolean flags. Ensure your provider is correctly implemented and handles potential initialization errors.
```ts
import { OpenFeature } from '@openfeature/web-sdk';
// Register your feature flag provider
try {
await OpenFeature.setProviderAndWait(new YourProviderOfChoice());
} catch (error) {
console.error('Failed to initialize provider:', error);
}
// create a new client
const client = OpenFeature.getClient();
// Evaluate your feature flag
const v2Enabled = client.getBooleanValue('v2_enabled', false);
if (v2Enabled) {
console.log('v2 is enabled');
}
```
--------------------------------
### Initialize Multi-Provider and Track Events
Source: https://github.com/open-feature/js-sdk/blob/main/packages/server/src/provider/multi-provider/README.md
Demonstrates how to initialize the Multi-Provider with multiple providers and send a tracking event. Tracking events are sent to all providers by default.
```typescript
import { OpenFeature } from '@openfeature/server-sdk';
import { MultiProvider } from '@openfeature/server-sdk';
const multiProvider = new MultiProvider([{ provider: new ProviderA() }, { provider: new ProviderB() }]);
await OpenFeature.setProviderAndWait(multiProvider);
const client = OpenFeature.getClient();
// Tracked events will be sent to all providers by default
client.track('purchase', { targetingKey: 'user123' }, { value: 99.99, currency: 'USD' });
```
--------------------------------
### Run End-to-End Tests (Web)
Source: https://github.com/open-feature/js-sdk/blob/main/CONTRIBUTING.md
Execute the end-to-end tests for the web client implementation. Ensure your development environment is set up correctly before running.
```bash
npm run e2e-web
```
--------------------------------
### Boolean Feature Flag Directive Example
Source: https://github.com/open-feature/js-sdk/blob/main/packages/angular/projects/angular-sdk/README.md
Use the `*booleanFeatureFlag` directive for conditional rendering based on a boolean feature flag. The content is shown when the flag is enabled.
```html
This is shown when the feature flag is enabled.
```
--------------------------------
### Navigate to Repository Directory
Source: https://github.com/open-feature/js-sdk/blob/main/CONTRIBUTING.md
Change your current directory to the cloned js-sdk repository. This is necessary to run subsequent commands within the project context.
```bash
cd openfeature-js-sdk
```
--------------------------------
### Stage, Commit, and Push Changes
Source: https://github.com/open-feature/js-sdk/blob/main/CONTRIBUTING.md
Stage all your changes, commit them with a signoff, and push the new branch to your fork. This prepares your work for a pull request.
```bash
git add --all
git commit --signoff
git push fork feat/NAME_OF_FEATURE
```
--------------------------------
### Registering Providers with Domains
Source: https://github.com/open-feature/js-sdk/blob/main/packages/web/README.md
Demonstrates how to register a default provider and domain-specific providers using the OpenFeature SDK. This allows for logical separation and management of clients.
```typescript
import { OpenFeature, TypedInMemoryProvider } from '@openfeature/web-sdk';
const myFlags = {
v2_enabled: {
variants: {
on: true,
off: false,
},
disabled: false,
defaultVariant: 'on',
},
} as const;
// Registering the default provider
OpenFeature.setProvider(new TypedInMemoryProvider(myFlags));
// Registering a provider to a domain
OpenFeature.setProvider('my-domain', new TypedInMemoryProvider(someOtherFlags));
// A Client bound to the default provider
const clientWithDefault = OpenFeature.getClient();
// A Client bound to the TypedInMemoryProvider provider
const domainScopedClient = OpenFeature.getClient('my-domain');
```
--------------------------------
### Test Declarative FeatureFlag Components
Source: https://github.com/open-feature/js-sdk/blob/main/packages/react/README.md
Use flagValueMap with OpenFeatureTestProvider to test declarative FeatureFlag components. This example shows setting values for 'new-feature' and 'theme' flags.
```tsx
// testing declarative FeatureFlag components
```
--------------------------------
### Initialize Multi-Provider with FirstSuccessfulStrategy
Source: https://github.com/open-feature/js-sdk/blob/main/packages/web/src/provider/multi-provider/README.md
Configure the Multi-Provider to use the FirstSuccessfulStrategy, which returns the first successful result and skips any provider that returns an error.
```typescript
import { MultiProvider, FirstSuccessfulStrategy } from '@openfeature/web-sdk';
const multiProvider = new MultiProvider(
[{ provider: new ProviderA() }, { provider: new ProviderB() }],
new FirstSuccessfulStrategy(),
);
```
--------------------------------
### Clone the js-sdk Repository
Source: https://github.com/open-feature/js-sdk/blob/main/CONTRIBUTING.md
Clone the official js-sdk repository to your local machine. This is the first step in setting up your development environment for contributions.
```bash
git clone https://github.com/open-feature/js-sdk.git openfeature-js-sdk
```
--------------------------------
### Basic Multi-Provider Tracking Usage
Source: https://github.com/open-feature/js-sdk/blob/main/packages/web/src/provider/multi-provider/README.md
Demonstrates how to initialize a `MultiProvider` with multiple providers and use the `track` method to send events to all configured providers. Events are sent to all providers by default.
```typescript
import { MultiProvider } from '@openfeature/web-sdk';
import { OpenFeature } from '@openfeature/web-sdk';
const multiProvider = new MultiProvider([{ provider: new ProviderA() }, { provider: new ProviderB() }]);
await OpenFeature.setProviderAndWait(multiProvider);
const client = OpenFeature.getClient();
// Tracked events will be sent to all providers by default
client.track('user-conversion', {
value: 99.99,
currency: 'USD',
conversionType: 'purchase',
});
client.track('page-view', {
page: '/checkout',
source: 'direct',
});
```
--------------------------------
### Initialize Multi-Provider with ComparisonStrategy
Source: https://github.com/open-feature/js-sdk/blob/main/packages/server/src/provider/multi-provider/README.md
Initialize the Multi-Provider with the 'ComparisonStrategy'. This strategy evaluates providers in parallel and uses a fallback provider if values do not agree. It accepts a fallback provider and an optional mismatch callback.
```typescript
import { MultiProvider, ComparisonStrategy } from '@openfeature/server-sdk';
const providerA = new ProviderA();
const multiProvider = new MultiProvider(
[{ provider: providerA }, { provider: new ProviderB() }],
new ComparisonStrategy(providerA, (details) => {
console.log('Mismatch detected', details);
}),
);
```
--------------------------------
### Run End-to-End Tests (Server)
Source: https://github.com/open-feature/js-sdk/blob/main/CONTRIBUTING.md
Execute the end-to-end tests for the server-side implementation. Ensure your development environment is set up correctly before running.
```bash
npm run e2e-server
```
--------------------------------
### Initialize Multi-Provider with Default Strategy
Source: https://github.com/open-feature/js-sdk/blob/main/packages/web/src/provider/multi-provider/README.md
Initialize the Multi-Provider with an array of providers. The default strategy evaluates providers sequentially and returns the first successful result, skipping FLAG_NOT_FOUND errors.
```typescript
import { MultiProvider } from '@openfeature/web-sdk';
import { OpenFeature } from '@openfeature/web-sdk';
const multiProvider = new MultiProvider([{ provider: new ProviderA() }, { provider: new ProviderB() }]);
await OpenFeature.setProviderAndWait(multiProvider);
const client = OpenFeature.getClient();
console.log('Evaluating flag');
console.log(client.getBooleanDetails('my-flag', false));
```
--------------------------------
### OpenFeatureProvider with Client Instance
Source: https://github.com/open-feature/js-sdk/blob/main/packages/react/README.md
Configures the `OpenFeatureProvider` by passing a pre-configured `Client` instance directly. This allows for more explicit control over the client used by the provider.
```tsx
const client = OpenFeature.getClient('my-domain');
function App() {
return (
);
}
```
--------------------------------
### Initialize Multi-Provider with FirstSuccessfulStrategy
Source: https://github.com/open-feature/js-sdk/blob/main/packages/server/src/provider/multi-provider/README.md
Initialize the Multi-Provider with a custom strategy, 'FirstSuccessfulStrategy', to alter the default evaluation behavior. This strategy skips providers that return an error.
```typescript
import { MultiProvider, FirstSuccessfulStrategy } from '@openfeature/server-sdk';
const multiProvider = new MultiProvider(
[{ provider: new ProviderA() }, { provider: new ProviderB() }],
new FirstSuccessfulStrategy(),
);
```
--------------------------------
### Bootstrap Application with Standalone Configuration
Source: https://github.com/open-feature/js-sdk/blob/main/packages/angular/projects/angular-sdk/README.md
Bootstrap your Angular application using the `appConfig` that includes the `provideOpenFeature()` configuration.
```typescript
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app/app.component';
import { appConfig } from './app/app.config';
bootstrapApplication(AppComponent, appConfig);
```
--------------------------------
### Simulate Provider Startup Delay
Source: https://github.com/open-feature/js-sdk/blob/main/packages/react/README.md
Introduce an artificial delay (in milliseconds) to the provider startup using delayMs. This is useful for testing suspense boundaries or loaders affected by feature flag availability.
```tsx
// delay the provider start by 1000ms and then return `true` for all evaluations of `'my-boolean-flag'`
```
--------------------------------
### Initialize Multi-Provider with ComparisonStrategy
Source: https://github.com/open-feature/js-sdk/blob/main/packages/web/src/provider/multi-provider/README.md
Utilize the ComparisonStrategy for scenarios where providers should return identical results. It evaluates all providers and uses a fallback provider if values differ, with an optional callback for mismatch notifications.
```typescript
import { MultiProvider, ComparisonStrategy } from '@openfeature/web-sdk';
const providerA = new ProviderA();
const multiProvider = new MultiProvider(
[{ provider: providerA }, { provider: new ProviderB() }],
new ComparisonStrategy(providerA, (details) => {
console.log('Mismatch detected', details);
}),
);
```
--------------------------------
### Handling Provider Events
Source: https://github.com/open-feature/js-sdk/blob/main/packages/server/README.md
Shows how to subscribe to provider events like Ready and Error at both the global OpenFeature API level and for specific clients.
```typescript
import { OpenFeature, ProviderEvents } from '@openfeature/server-sdk';
OpenFeature.addHandler(ProviderEvents.Ready, (eventDetails) => {
console.log(`Ready event from: ${eventDetails?.providerName}:`, eventDetails);
});
const client = OpenFeature.getClient();
client.addHandler(ProviderEvents.Error, (eventDetails) => {
console.log(`Error event from: ${eventDetails?.providerName}:`, eventDetails);
});
```
--------------------------------
### Handling Provider Events
Source: https://github.com/open-feature/js-sdk/blob/main/packages/web/README.md
Illustrates how to subscribe to OpenFeature provider events, such as readiness and errors, using both the global OpenFeature API and specific client instances. This enables reacting to state changes.
```typescript
import { OpenFeature, ProviderEvents } from '@openfeature/web-sdk';
// OpenFeature API
OpenFeature.addHandler(ProviderEvents.Ready, (eventDetails) => {
console.log(`Ready event from: ${eventDetails?.providerName}:`, eventDetails);
});
// Specific client
const client = OpenFeature.getClient();
client.addHandler(ProviderEvents.Error, (eventDetails) => {
console.log(`Error event from: ${eventDetails?.providerName}:`, eventDetails);
});
```
--------------------------------
### Add Fork as Remote Origin
Source: https://github.com/open-feature/js-sdk/blob/main/CONTRIBUTING.md
Configure your local repository to point to your personal fork on GitHub. This allows you to push your changes to your fork.
```bash
git remote add fork https://github.com/YOUR_GITHUB_USERNAME/js-sdk.git
```
--------------------------------
### Custom Logging Configuration
Source: https://github.com/open-feature/js-sdk/blob/main/packages/server/README.md
Illustrates how to override the default console logging behavior by providing a custom logger implementation globally or per client.
```typescript
import type { Logger } from '@openfeature/server-sdk';
const logger: Logger = console;
OpenFeature.setLogger(logger);
const client = OpenFeature.getClient();
client.setLogger(logger);
```
--------------------------------
### Configure Multi-Provider with First Match Strategy
Source: https://github.com/open-feature/js-sdk/blob/main/packages/server/README.md
Set up a Multi-Provider to use multiple underlying providers. The `FirstMatchStrategy` ensures that the first provider to successfully return a flag value is used, short-circuiting on errors.
```typescript
import { OpenFeature, MultiProvider, FirstMatchStrategy } from '@openfeature/server-sdk';
// Create providers
const primaryProvider = new YourPrimaryProvider();
const backupProvider = new YourBackupProvider();
// Create multi-provider with a strategy
const multiProvider = new MultiProvider(
[{ provider: primaryProvider }, { provider: backupProvider }],
new FirstMatchStrategy(),
);
// Register the multi-provider
await OpenFeature.setProviderAndWait(multiProvider);
// Use as normal
const client = OpenFeature.getClient();
const value = await client.getBooleanValue('my-flag', false);
```
--------------------------------
### Register Provider Asynchronously
Source: https://github.com/open-feature/js-sdk/blob/main/packages/web/README.md
Use `setProviderAndWait` to register a provider and ensure it's ready before proceeding. Handles potential initialization errors.
```typescript
try {
await OpenFeature.setProviderAndWait(new MyProvider());
} catch (error) {
console.error('Failed to initialize provider:', error);
}
```
--------------------------------
### Register Provider Awaitably
Source: https://github.com/open-feature/js-sdk/blob/main/packages/server/README.md
Use `setProviderAndWait` to register a provider and ensure it's ready before proceeding. This is useful for ensuring flag data is available immediately after initialization.
```typescript
await OpenFeature.setProviderAndWait(new MyProvider());
```
--------------------------------
### Register Hooks Globally, Client-wide, and Per-Evaluation
Source: https://github.com/open-feature/js-sdk/blob/main/packages/web/README.md
Demonstrates how to add hooks at different scopes: globally for all evaluations, on a specific client, or for a single flag evaluation.
```typescript
import { OpenFeature } from '@openfeature/web-sdk';
// add a hook globally, to run on all evaluations
OpenFeature.addHooks(new ExampleGlobalHook());
// add a hook on this client, to run on all evaluations made by this client
const client = OpenFeature.getClient();
client.addHooks(new ExampleClientHook());
// add a hook for this evaluation only
const boolValue = client.getBooleanValue('bool-flag', false, { hooks: [new ExampleHook()] });
```
--------------------------------
### OpenFeatureProvider with Domain
Source: https://github.com/open-feature/js-sdk/blob/main/packages/react/README.md
Configures the `OpenFeatureProvider` to use a specific domain, allowing flags within that domain to be associated with a particular client or provider. This is an alternative to passing a pre-configured `Client` instance.
```tsx
// Flags within this domain will use the client/provider associated with `my-domain`,
function App() {
return (
);
}
```
--------------------------------
### Configure OpenFeatureProvider with a Domain
Source: https://github.com/open-feature/js-sdk/blob/main/packages/react/README.md
Use the `domain` parameter on `OpenFeatureProvider` to scope a client to a particular provider and context when using multiple providers.
```tsx
```
--------------------------------
### Setting Context for Domain-Scoped Clients
Source: https://github.com/open-feature/js-sdk/blob/main/packages/web/README.md
Shows how to set evaluation context for domain-scoped clients, either during provider registration or by updating context after registration. This allows for personalized flag evaluations.
```typescript
OpenFeature.setProvider('my-domain', new NewCachedProvider(), { targetingKey: localStorage.getItem('targetingKey') });
```
```typescript
await OpenFeature.setContext('my-domain', { targetingKey: localStorage.getItem('targetingKey') });
```
--------------------------------
### Customizing Tracking with CustomTrackingStrategy
Source: https://github.com/open-feature/js-sdk/blob/main/packages/web/src/provider/multi-provider/README.md
Illustrates how to customize tracking behavior by extending `FirstMatchStrategy` and overriding the `shouldTrackWithThisProvider` method. This allows selective tracking based on provider name or event type.
```typescript
import { FirstMatchStrategy, StrategyPerProviderContext } from '@openfeature/web-sdk';
class CustomTrackingStrategy extends FirstMatchStrategy {
// Override tracking behavior
override shouldTrackWithThisProvider(
strategyContext: StrategyPerProviderContext,
context: EvaluationContext,
trackingEventName: string,
trackingEventDetails: TrackingEventDetails,
): boolean {
// Only track with the primary provider
if (strategyContext.providerName === 'primary-provider') {
return true;
}
// Skip tracking for analytics events on backup providers
if (trackingEventName.startsWith('analytics.')) {
return false;
}
return super.shouldTrackWithThisProvider(strategyContext, context, trackingEventName, trackingEventDetails);
}
}
```
--------------------------------
### Set Provider with Initial Context
Source: https://github.com/open-feature/js-sdk/blob/main/packages/web/README.md
Register a new provider with initial context data. This context will be used for flag evaluations.
```typescript
await OpenFeature.setProvider(new MyProvider(), { origin: document.location.host });
```
--------------------------------
### Create a New Feature Branch
Source: https://github.com/open-feature/js-sdk/blob/main/CONTRIBUTING.md
Create a new branch for your feature or bugfix. Use a descriptive name following the 'feat/NAME_OF_FEATURE' or 'fix/NAME_OF_BUG' convention.
```bash
git checkout -b feat/NAME_OF_FEATURE
```
--------------------------------
### Setting Evaluation Context
Source: https://github.com/open-feature/js-sdk/blob/main/packages/server/README.md
Demonstrates how to set evaluation context at global, client, and invocation levels for dynamic flag targeting.
```typescript
OpenFeature.setContext({ region: 'us-east-1' });
const client = OpenFeature.getClient();
client.setContext({ version: process.env.APP_VERSION });
const requestContext = {
targetingKey: req.session.id,
email: req.session.email,
product: req.productId,
};
const boolValue = await client.getBooleanValue('some-flag', false, requestContext);
```
--------------------------------
### Tracking User Actions with OpenFeature
Source: https://github.com/open-feature/js-sdk/blob/main/packages/server/README.md
This snippet shows how to associate user actions with feature flag evaluations for experimentation. After a flag is evaluated, the `client.track` function can be called to record specific events, linking user behavior to feature flag usage.
```typescript
// flag is evaluated
await client.getBooleanValue('new-feature', false);
// new feature is used and track function is called recording the usage
useNewFeature();
client.track('new-feature-used');
```
--------------------------------
### Custom Evaluation Strategy Implementation
Source: https://github.com/open-feature/js-sdk/blob/main/packages/server/src/provider/multi-provider/README.md
Shows how to create a custom evaluation strategy by extending the BaseEvaluationStrategy. This allows for custom logic in provider evaluation and result determination.
```typescript
import { FirstMatchStrategy } from '@openfeature/server-sdk';
class MyCustomStrategy extends FirstMatchStrategy {
// Override methods as needed
override shouldEvaluateThisProvider(
strategyContext: StrategyPerProviderContext,
evalContext: EvaluationContext,
): boolean {
// Custom logic here
return super.shouldEvaluateThisProvider(strategyContext, evalContext);
}
}
```
--------------------------------
### Registering Hooks Globally, Per Client, and Per Invocation
Source: https://github.com/open-feature/js-sdk/blob/main/packages/server/README.md
Shows how to register custom hooks at different scopes: globally for all evaluations, on a specific client, or for a single flag evaluation.
```typescript
import { OpenFeature } from '@openfeature/server-sdk';
OpenFeature.addHooks(new ExampleGlobalHook());
const client = OpenFeature.getClient();
client.addHooks(new ExampleClientHook());
const boolValue = await client.getBooleanValue('bool-flag', false, { hooks: [new ExampleHook()] });
```
--------------------------------
### FeatureFlagService Usage with Observables
Source: https://github.com/open-feature/js-sdk/blob/main/packages/angular/projects/angular-sdk/README.md
Demonstrates how to use the FeatureFlagService to fetch feature flag details (boolean, string, number, object) and subscribe to their changes using Observables and the AsyncPipe.
```APIDOC
## FeatureFlagService
The `FeatureFlagService` provides programmatic access to feature flags through reactive patterns. All methods return Observables that automatically emit new values when flag configurations or evaluation context changes.
### Method Signature
`getBooleanDetails(flagKey: string, defaultValue: boolean, options?: FlagOptions): Observable>`
`getStringDetails(flagKey: string, defaultValue: string, options?: FlagOptions): Observable>`
`getNumberDetails(flagKey: string, defaultValue: number, options?: FlagOptions): Observable>`
`getObjectDetails(flagKey: string, defaultValue: T, options?: FlagOptions): Observable>`
### Parameters
- **flagKey** (string) - Required - The key of the feature flag.
- **defaultValue** (boolean | string | number | object) - Required - The default value to return if the flag is not found or an error occurs.
- **options** (FlagOptions) - Optional - Options to configure flag evaluation behavior, such as `updateOnConfigurationChanged` and `updateOnContextChanged`.
### Request Example
```typescript
import { Component, inject } from '@angular/core';
import { AsyncPipe } from '@angular/common';
import { FeatureFlagService } from '@openfeature/angular-sdk';
@Component({
selector: 'my-component',
standalone: true,
imports: [AsyncPipe],
template: `
Feature is enabled! Reason: {{ (isFeatureEnabled$ | async)?.reason }}
Theme: {{ (currentTheme$ | async)?.value }}
Max items: {{ (maxItems$ | async)?.value }}
`,
})
export class MyComponent {
private flagService = inject(FeatureFlagService);
// Boolean flag
isFeatureEnabled$ = this.flagService.getBooleanDetails('my-feature', false);
// String flag
currentTheme$ = this.flagService.getStringDetails('theme', 'light');
// Number flag
maxItems$ = this.flagService.getNumberDetails('max-items', 10);
// Object flag with type safety
config$ = this.flagService.getObjectDetails<{ timeout: number }>('api-config', { timeout: 5000 });
}
```
### Response
- **value** (any) - The evaluated value of the feature flag.
- **reason** (string) - The reason for the flag evaluation (e.g., `"TARGETING_MATCH"`, `"DEFAULT"`, `"ERROR"`).
- **flagMetadata** (object) - Metadata associated with the flag evaluation.
```
--------------------------------
### Tracking Feature Flag Usage
Source: https://github.com/open-feature/js-sdk/blob/main/packages/web/README.md
Demonstrates how to associate user actions with feature flag evaluations using the `track` function. This is useful for experimentation and understanding user engagement with new features.
```typescript
// flag is evaluated
client.getBooleanValue('new-feature', false);
// new feature is used and track function is called recording the usage
useNewFeature();
client.track('new-feature-used');
```
--------------------------------
### Set Initial Evaluation Context with Factory Function
Source: https://github.com/open-feature/js-sdk/blob/main/packages/angular/projects/angular-sdk/README.md
Configure the OpenFeature Angular SDK with a factory function that returns an evaluation context. This allows for dynamic context loading, such as from local storage, when the SDK is provided.
```typescript
import { ApplicationConfig } from '@angular/core';
import { provideOpenFeature, EvaluationContext } from '@openfeature/angular-sdk';
const contextFactory = (): EvaluationContext => loadContextFromLocalStorage();
export const appConfig: ApplicationConfig = {
providers: [
provideOpenFeature({
provider: yourFeatureProvider,
context: contextFactory,
}),
],
};
```
--------------------------------
### Register Provider Synchronously
Source: https://github.com/open-feature/js-sdk/blob/main/packages/server/README.md
Use `setProvider` for synchronous provider registration. This method registers the provider without waiting for it to be ready, which might be suitable in certain application flows.
```typescript
OpenFeature.setProvider(new MyProvider());
```
--------------------------------
### Track User Actions with Feature Flags
Source: https://github.com/open-feature/js-sdk/blob/main/packages/react/README.md
Use the `useTrack` hook to associate user actions with feature flag evaluations for robust experimentation. Call the `track` function with an event name and optional details within your component.
```tsx
function MyComponent() {
// get a tracking function for this .
const { track } = useTrack();
// call the tracking event
// can be done in render, useEffect, or in handlers, depending on your use case
track(eventName, trackingDetails);
return <>...>;
}
```
--------------------------------
### FeatureFlagService Usage with Angular Signals
Source: https://github.com/open-feature/js-sdk/blob/main/packages/angular/projects/angular-sdk/README.md
Shows how to convert Observables returned by FeatureFlagService into Angular Signals using `toSignal` for reactive programming with Signals.
```APIDOC
## FeatureFlagService with Signals
You can convert any Observable from the service to an Angular Signal using `toSignal()`:
### Method Signature
`toSignal(observable: Observable, options?: ToSignalOptions): Signal`
### Parameters
- **observable** (Observable) - Required - The Observable to convert.
- **options** (ToSignalOptions) - Optional - Options for `toSignal`.
### Request Example
```typescript
import { Component, inject } from '@angular/core';
import { toSignal } from '@angular/core/rxjs-interop';
import { FeatureFlagService } from '@openfeature/angular-sdk';
@Component({
selector: 'my-component',
standalone: true,
template: `
Feature is enabled! Reason: {{ isFeatureEnabled()?.reason }}
Theme: {{ currentTheme()?.value }}
`,
})
export class MyComponent {
private flagService = inject(FeatureFlagService);
// Convert Observables to Signals
isFeatureEnabled = toSignal(this.flagService.getBooleanDetails('my-feature', false));
currentTheme = toSignal(this.flagService.getStringDetails('theme', 'light'));
}
```
### Response
- **Signal>** - A Signal that holds the latest evaluated flag details.
```
--------------------------------
### FeatureFlag Component Usage
Source: https://github.com/open-feature/js-sdk/blob/main/packages/react/README.md
Demonstrates various ways to use the `FeatureFlag` component for conditional rendering based on flag values, including basic usage, matching specific values, boolean flags with fallbacks, custom predicates, and function children for accessing flag details.
```tsx
import { FeatureFlag } from '@openfeature/react-sdk';
function App() {
return (
{/* Basic usage - renders children when flag is truthy */}
{/* Match specific values */}
{/* Boolean flag with fallback */}
}>
{/* Custom predicate function for complex matching */}
!!expected && actual.value.includes(expected)}
>
{/* Function as children for accessing flag details */}
{( { value, reason } ) => (
value is {value}, reason is {reason?.toString()}
)}
);
}
```
--------------------------------
### Standalone Configuration for Angular Apps
Source: https://github.com/open-feature/js-sdk/blob/main/packages/angular/projects/angular-sdk/README.md
Configure OpenFeature for standalone Angular applications by providing `provideOpenFeature()` in the `providers` array of your `ApplicationConfig`. This is the recommended approach.
```typescript
import { ApplicationConfig } from '@angular/core';
import { provideOpenFeature } from '@openfeature/angular-sdk';
export const appConfig: ApplicationConfig = {
providers: [
provideOpenFeature({
provider: yourFeatureProvider,
// domainBoundProviders are optional, mostly needed if more than one provider is used in the application.
domainBoundProviders: {
domain1: new YourOpenFeatureProvider(),
domain2: new YourOtherOpenFeatureProvider(),
},
}),
],
};
```
--------------------------------
### NgModule Configuration for OpenFeature (Deprecated)
Source: https://github.com/open-feature/js-sdk/blob/main/packages/angular/projects/angular-sdk/README.md
Configure OpenFeature for NgModule-based applications by importing `OpenFeatureModule` and calling `forRoot()`. This method is deprecated in favor of standalone configuration.
```typescript
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { OpenFeatureModule } from '@openfeature/angular-sdk';
@NgModule({
declarations: [
// Other components
],
imports: [
CommonModule,
OpenFeatureModule.forRoot({
provider: yourFeatureProvider,
// domainBoundProviders are optional, mostly needed if more than one provider is used in the application.
domainBoundProviders: {
domain1: new YourOpenFeatureProvider(),
domain2: new YourOtherOpenFeatureProvider(),
},
}),
],
})
export class AppModule {}
```
--------------------------------
### Feature Flag Directives
Source: https://github.com/open-feature/js-sdk/blob/main/packages/angular/projects/angular-sdk/README.md
Illustrates how to use structural directives like `*stringFeatureFlag` to conditionally render templates based on feature flag values and evaluation details.
```APIDOC
## Feature Flag Directives
The `*stringFeatureFlag` directive can be used for conditional rendering based on flag values.
### Directive Usage
`*stringFeatureFlag="''; value: ''; default: ''; else: ; let ; let details = evaluationDetails"
### Parameters
- **flagKey** (string) - Required - The key of the feature flag.
- **value** (any) - Optional - The expected value of the flag for the template to be rendered.
- **default** (any) - Optional - The default value to use if the flag is not evaluated or an error occurs.
- **else** (TemplateRef) - Optional - A reference to an ng-template to render if the condition is not met.
- **let ** - Optional - Binds the flag's evaluated value to a template variable.
- **let details = evaluationDetails** - Optional - Binds the full evaluation details object to a template variable.
### Request Example
```html
It was a match! The theme color is {{ value }} because of {{ details.reason }}
It was no match! The theme color is {{ value }} because of {{ details.reason }}
```
When the expected flag value is omitted, the template will always be rendered.
```html
The theme color is {{ value }}.
```
```