@pl4yzonellc/valar-ui-connector
v0.0.2
Published
Reusable Angular library for loading and reading feature flags (`boolean`, `string`, `number`) with: - Strictly typed flag models per app - Startup loading via `APP_INITIALIZER` - Default fallback behavior on HTTP errors
Readme
valar-ui-connector
Reusable Angular library for loading and reading feature flags (boolean, string, number) with:
- Strictly typed flag models per app
- Startup loading via
APP_INITIALIZER - Default fallback behavior on HTTP errors
Public API
import {
FeatureFlagsService,
FeatureFlagsConfig,
FEATURE_FLAGS_CONFIG,
provideFeatureFlags
} from '@pl4yzonellc/valar-ui-connector';Consumer Setup
- Define app-specific flags and defaults:
// app-feature-flags.model.ts
export interface AppFeatureFlags {
showConsultationForm: boolean;
uiTheme: string;
maxItems: number;
}
export const APP_DEFAULT_FEATURE_FLAGS: AppFeatureFlags = {
showConsultationForm: false,
uiTheme: 'light',
maxItems: 20,
};- Register providers in
AppModule:
import { NgModule } from '@angular/core';
import { provideHttpClient } from '@angular/common/http';
import { provideFeatureFlags } from '@pl4yzonellc/valar-ui-connector';
import { environment } from '../environments/environment';
import { AppFeatureFlags, APP_DEFAULT_FEATURE_FLAGS } from './app-feature-flags.model';
@NgModule({
providers: [
provideHttpClient(),
...provideFeatureFlags<AppFeatureFlags>({
endpoint: `${environment.baseURL}/feature-flags/tenant_${environment.tenantId}`,
defaults: APP_DEFAULT_FEATURE_FLAGS,
// optional:
// httpOptions: { withCredentials: true, headers: { ... } }
// map nested payloads, e.g. { uiOptions: {...} }:
// mapResponse: (response) => (response as { uiOptions?: Partial<AppFeatureFlags> })?.uiOptions
}),
],
})
export class AppModule {}- Use the service anywhere:
import { Injectable } from '@angular/core';
import { FeatureFlagsService } from '@pl4yzonellc/valar-ui-connector';
import { AppFeatureFlags } from './app-feature-flags.model';
@Injectable({ providedIn: 'root' })
export class ExampleService {
constructor(private readonly flags: FeatureFlagsService<AppFeatureFlags>) {}
canShowConsultationForm(): boolean {
return this.flags.isEnabled('showConsultationForm');
}
}Use isEnabled(...) for boolean keys and getFlag(...) for any typed value:
const enabled = this.flags.isEnabled('showConsultationForm'); // boolean
const theme = this.flags.getFlag('uiTheme'); // string
const maxItems = this.flags.getFlag('maxItems'); // numberMigration from local FeatureFlagService
Use this when an app already has a local service such as
src/app/tenant/backend-services/feature-flag.service.ts.
- Create a typed model and defaults:
// src/app/feature-flags.model.ts
export interface AppFeatureFlags {
showConsultationForm: boolean;
}
export const APP_DEFAULT_FEATURE_FLAGS: AppFeatureFlags = {
showConsultationForm: false,
};- Replace local
APP_INITIALIZERwiring with library provider:
Before:
providers: [
{
provide: APP_INITIALIZER,
useFactory: initializeFeatureFlags,
deps: [FeatureFlagService],
multi: true,
}
]After:
import { provideFeatureFlags } from '@pl4yzonellc/valar-ui-connector';
import { APP_DEFAULT_FEATURE_FLAGS, AppFeatureFlags } from './feature-flags.model';
import { environment } from '../environments/environment';
providers: [
...provideFeatureFlags<AppFeatureFlags>({
endpoint: `${environment.baseURL}/feature-flags/tenant_${environment.tenantId}`,
defaults: APP_DEFAULT_FEATURE_FLAGS,
}),
]- Replace service imports and injection:
Before:
import { FeatureFlagService } from 'src/app/tenant/backend-services/feature-flag.service';After:
import { FeatureFlagsService } from '@pl4yzonellc/valar-ui-connector';
import { AppFeatureFlags } from 'src/app/feature-flags.model';Inject:
constructor(private readonly flags: FeatureFlagsService<AppFeatureFlags>) {}- Replace old method calls:
getFlags()->getAll()getFlagByKey('showConsultationForm')->getFlag('showConsultationForm')isEnabled('showConsultationForm')remains supported
- Remove local
FeatureFlagServiceand initializer factory after app compiles.
Behavior
- On app startup,
loadFlags()is called once throughAPP_INITIALIZER. - Successful response values are merged with defaults.
- If the HTTP request fails, defaults are kept and a warning is logged.
Endpoint Contract
GET <endpoint> should return a partial flag object. Example:
{
"showConsultationForm": true
}Unknown keys are ignored by your app if they are not part of the typed flag model.
Build
ng build valar-ui-connectorTest
ng test valar-ui-connector