billdogeng-angular
v1.0.0-beta.1
Published
BilldogEng SDK for Angular — idiomatic wrapper over the BillDog engagement suite (analytics, surveys, in-app messaging, remote feature flags)
Maintainers
Readme
billdogeng-angular
Idiomatic Angular wrapper over the BillDog engagement suite — a thin layer
on top of the browser SDK (@billdog.io/web) exposing:
- Analytics —
capture,identify,group - Surveys — fetch / list / submit + a ready-to-use
<billdog-survey>component powered by the rich shared renderer (pagination, welcome / thank-you screens, compound logic, and every widget: emoji / thumbs / NPS / rating / matrix / ranking / slider / dropdown …) — full parity with the iOS/Android renderers - In-app messaging — trigger queued messages
- Feature flags — remote / server-authoritative (no local bucketing or hashing)
It is SSR-safe: importing the package never touches window/document, and
BilldogService.init() no-ops during Angular Universal prerender, activating only
on the client after hydration.
Install
npm install billdogeng-angular @billdog.io/web@angular/core, @angular/common, and rxjs are peer dependencies.
Quickstart (standalone APIs)
// main.ts
import { bootstrapApplication } from '@angular/platform-browser';
import { provideBilldog } from 'billdogeng-angular';
import { AppComponent } from './app/app.component';
bootstrapApplication(AppComponent, {
providers: [
provideBilldog({
config: { apiKey: 'bd_test_xxx', projectId: 'proj_123' },
// autoInit defaults to true (runs via APP_INITIALIZER, SSR-safe)
}),
],
});Use the service anywhere:
import { Component } from '@angular/core';
import { BilldogService } from 'billdogeng-angular';
@Component({ selector: 'app-checkout', standalone: true, template: '...' })
export class CheckoutComponent {
constructor(private billdog: BilldogService) {}
async onPurchase() {
await this.billdog.identify('user_42', { email: '[email protected]' });
await this.billdog.capture('purchase_completed', { plan: 'pro' });
await this.billdog.group('company', 'acme');
}
}Feature flags (remote)
// imperative
const enabled = this.billdog.isFeatureEnabled('new-checkout');
const variant = this.billdog.getFeatureFlag('cta-color'); // string | boolean
const payload = this.billdog.getFeatureFlagPayload('new-checkout');
// reactive
this.billdog.watchFeatureFlag('new-checkout').subscribe(v => /* ... */);
// force a fresh remote evaluation
await this.billdog.reloadFeatureFlags();Flags are evaluated on the server — this SDK only reads resolved values.
Template directive:
<div *billdogFeatureFlag="'new-dashboard'">Only shown when the remote flag is on</div>Surveys
Drop-in component (fetches the survey by id, renders it with the rich shared renderer, and submits canonical answers). The renderer is React mounted on the client only, so the component is SSR-safe to import:
<billdog-survey
surveyId="survey_123"
[customerId]="userId"
(completed)="onSurveyDone($event)"
(dismissed)="onSurveyDismissed()"
(errored)="onSurveyError($event)"
></billdog-survey>completed emits { result, answers } where answers are in the canonical
backend shape ({ question_id, choice_id?, answer_text?, answer_number?,
answer_json? }). dismissed fires when the user closes the survey without
submitting.
Requires
reactandreact-dom(>= 18) as peer deps — they are loaded lazily on the client only and never imported during SSR.
Or fetch/submit imperatively:
const survey = await this.billdog.fetchSurvey('survey_123', userId);
await this.billdog.submitSurvey('survey_123', [
{ question_id: 'q1', choice_id: 'c1' },
{ question_id: 'q2', answer_text: 'great!' },
]);In-app messaging
await this.billdog.showInAppMessages('home');Classic NgModule apps
import { BilldogModule } from 'billdogeng-angular';
@NgModule({
imports: [
BilldogModule.forRoot({ config: { apiKey: 'bd_test_xxx', projectId: 'proj_123' } }),
],
})
export class AppModule {}Then import BilldogModule in feature modules to use <billdog-survey> and
*billdogFeatureFlag.
Testing
Provide a mock client via the BILLDOG_CLIENT token (or pass client to
provideBilldog) to drive the SDK without network access:
TestBed.configureTestingModule({
providers: [
{ provide: BILLDOG_CONFIG, useValue: { apiKey: 'bd_test', projectId: 'p' } },
{ provide: BILLDOG_CLIENT, useValue: myMockClient },
],
});License
MIT
