Skip to content

Commit

Permalink
[DSC-1570] Fix issue with missing providers for klaro service during SSR
Browse files Browse the repository at this point in the history
  • Loading branch information
atarix83 committed May 29, 2024
1 parent efd31bd commit 484e75e
Show file tree
Hide file tree
Showing 8 changed files with 112 additions and 71 deletions.
8 changes: 8 additions & 0 deletions src/app/app.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import { of } from 'rxjs';
import { APP_CONFIG } from '../config/app-config.interface';
import { environment } from '../environments/environment';
import { KlaroService } from './shared/cookies/klaro.service';
import { DatadogRumService } from './shared/datadog-rum/datadog-rum.service';

let comp: AppComponent;
let fixture: ComponentFixture<AppComponent>;
Expand All @@ -57,6 +58,7 @@ describe('App component', () => {
let breadcrumbsServiceSpy;
let routeServiceMock;
let klaroServiceSpy: jasmine.SpyObj<KlaroService>;
let datadogRumServiceSpy: jasmine.SpyObj<DatadogRumService>;

const getDefaultTestBedConf = () => {
breadcrumbsServiceSpy = jasmine.createSpyObj(['listenForRouteChanges']);
Expand All @@ -71,6 +73,11 @@ describe('App component', () => {
consentsUpdates$: of({})
});

datadogRumServiceSpy = jasmine.createSpyObj('DatadogRumService', {
initDatadogRum: jasmine.createSpy('initDatadogRum'),
getDatadogRumState: jasmine.createSpy('getDatadogRumState')
});

return {
imports: [
CommonModule,
Expand Down Expand Up @@ -99,6 +106,7 @@ describe('App component', () => {
{ provide: RouteService, useValue: routeServiceMock },
{ provide: APP_CONFIG, useValue: environment },
{ provide: KlaroService, useValue: klaroServiceSpy },
{ provide: DatadogRumService, useValue: datadogRumServiceSpy },
provideMockStore({ initialState }),
AppComponent,
// RouteService
Expand Down
4 changes: 1 addition & 3 deletions src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,7 @@ export class AppComponent implements OnInit, AfterViewInit {

this.dispatchWindowSize(this._window.nativeWindow.innerWidth, this._window.nativeWindow.innerHeight);

if (isPlatformBrowser(this.platformId)) {
this.datadogRumService.initDatadogRum();
}
this.datadogRumService.initDatadogRum();
}

private storeCSSVariables() {
Expand Down
67 changes: 67 additions & 0 deletions src/app/shared/datadog-rum/browser-datadog-rum.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { Injectable } from '@angular/core';
import { environment } from '../../../environments/environment';
import { datadogRum } from '@datadog/browser-rum';
import { CookieConsents, KlaroService } from '../cookies/klaro.service';
import { BehaviorSubject, Observable } from 'rxjs';
import { createSelector, Store } from '@ngrx/store';
import { setDatadogRumStatusAction } from './datadog-rum.actions';
import { DatadogRumState } from './datadog-rum.reducer';
import { distinctUntilChanged, take } from 'rxjs/operators';
import { coreSelector } from '../../core/core.selectors';
import { CoreState } from '../../core/core-state.model';
import { DatadogRumService } from './datadog-rum.service';

@Injectable()
export class BrowserDatadogRumService extends DatadogRumService {

consentsUpdates$: BehaviorSubject<CookieConsents>;
datadogRumStateSelector = createSelector(coreSelector, (state: CoreState) => state.datadogRum);

constructor(
private klaroService: KlaroService,
private store: Store
) {
super();
}

initDatadogRum() {
this.klaroService.watchConsentUpdates();
this.consentsUpdates$ = this.klaroService.consentsUpdates$;
this.consentsUpdates$.subscribe(savedPreferences => {
this.getDatadogRumState().subscribe((state) => {
if (savedPreferences?.datadog &&
environment.datadogRum?.clientToken && environment.datadogRum?.applicationId &&
environment.datadogRum?.service && environment.datadogRum?.env) {
if (!state.isInitialized) {
this.store.dispatch(new setDatadogRumStatusAction({
isInitialized: true,
isRunning: true
}));
datadogRum.init(environment.datadogRum);
} else if (!state.isRunning) {
this.store.dispatch(new setDatadogRumStatusAction({
isRunning: true
}));
datadogRum.startSessionReplayRecording();
}
} else {
datadogRum.stopSessionReplayRecording();
this.store.dispatch(new setDatadogRumStatusAction({
isRunning: false
}));
}
});
});
}


getDatadogRumState(): Observable<DatadogRumState> {
return this.store
.select(this.datadogRumStateSelector)
.pipe(
distinctUntilChanged(),
take(1),
);
}
}

11 changes: 6 additions & 5 deletions src/app/shared/datadog-rum/datadog-rum.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ import { CookieConsents, KlaroService } from '../cookies/klaro.service';
import { of } from 'rxjs';
import { environment } from '../../../environments/environment';
import { setDatadogRumStatusAction } from './datadog-rum.actions';
import { BrowserDatadogRumService } from './browser-datadog-rum.service';

describe('DatadogRumService', () => {
let service: DatadogRumService;
let service: BrowserDatadogRumService;
let store: MockStore;
let klaroService: KlaroService;
let memoizedSelector;
Expand Down Expand Up @@ -40,12 +41,12 @@ describe('DatadogRumService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
DatadogRumService,
provideMockStore({initialState}),
{provide: KlaroService, useValue: klaroServiceSpy},
{ provide: DatadogRumService, useClass: BrowserDatadogRumService },
provideMockStore({ initialState }),
{ provide: KlaroService, useValue: klaroServiceSpy },
]
});
service = TestBed.inject(DatadogRumService);
service = TestBed.inject(DatadogRumService) as BrowserDatadogRumService;
store = TestBed.inject(MockStore);
memoizedSelector = store.overrideSelector(service.datadogRumStateSelector, initialState.datadogRum);
klaroService = TestBed.inject(KlaroService);
Expand Down
68 changes: 6 additions & 62 deletions src/app/shared/datadog-rum/datadog-rum.service.ts
Original file line number Diff line number Diff line change
@@ -1,67 +1,11 @@
import { Injectable } from '@angular/core';
import { environment } from '../../../environments/environment';
import { datadogRum } from '@datadog/browser-rum';
import { CookieConsents, KlaroService } from '../cookies/klaro.service';
import { BehaviorSubject, Observable } from 'rxjs';
import { createSelector, Store } from '@ngrx/store';
import { setDatadogRumStatusAction } from './datadog-rum.actions';
import { DatadogRumState } from './datadog-rum.reducer';
import { distinctUntilChanged, take } from 'rxjs/operators';
import { coreSelector } from '../../core/core.selectors';
import { CoreState } from '../../core/core-state.model';

@Injectable({
providedIn: 'root'
})
export class DatadogRumService {
@Injectable()
export abstract class DatadogRumService {

consentsUpdates$: BehaviorSubject<CookieConsents>;
datadogRumStateSelector = createSelector(coreSelector, (state: CoreState) => state.datadogRum);

constructor(
private klaroService: KlaroService,
private store: Store
) {
}

initDatadogRum() {
this.klaroService.watchConsentUpdates();
this.consentsUpdates$ = this.klaroService.consentsUpdates$;
this.consentsUpdates$.subscribe(savedPreferences => {
this.getDatadogRumState().subscribe((state) => {
if (savedPreferences?.datadog &&
environment.datadogRum?.clientToken && environment.datadogRum?.applicationId &&
environment.datadogRum?.service && environment.datadogRum?.env) {
if (!state.isInitialized) {
this.store.dispatch(new setDatadogRumStatusAction({
isInitialized: true,
isRunning: true
}));
datadogRum.init(environment.datadogRum);
} else if (!state.isRunning) {
this.store.dispatch(new setDatadogRumStatusAction({
isRunning: true
}));
datadogRum.startSessionReplayRecording();
}
} else {
datadogRum.stopSessionReplayRecording();
this.store.dispatch(new setDatadogRumStatusAction({
isRunning: false
}));
}
});
});
}


getDatadogRumState(): Observable<DatadogRumState> {
return this.store
.select(this.datadogRumStateSelector)
.pipe(
distinctUntilChanged(),
take(1),
);
}
/**
* Initializes the service
*/
abstract initDatadogRum();
}

11 changes: 11 additions & 0 deletions src/app/shared/datadog-rum/server-datadog-rum.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Injectable } from '@angular/core';
import { DatadogRumService } from './datadog-rum.service';

@Injectable()
export class ServerDatadogRumService extends DatadogRumService {

initDatadogRum() {
return;
}
}

6 changes: 6 additions & 0 deletions src/modules/app/browser-app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ import { ReferrerService } from '../../app/core/services/referrer.service';
import { BrowserReferrerService } from '../../app/core/services/browser.referrer.service';
import { MathService } from '../../app/core/shared/math.service';
import { ClientMathService } from '../../app/core/shared/client-math.service';
import { DatadogRumService } from '../../app/shared/datadog-rum/datadog-rum.service';
import { BrowserDatadogRumService } from '../../app/shared/datadog-rum/browser-datadog-rum.service';

export const REQ_KEY = makeStateKey<string>('req');

Expand Down Expand Up @@ -87,6 +89,10 @@ export function getRequest(transferState: TransferState): any {
provide: KlaroService,
useClass: BrowserKlaroService
},
{
provide: DatadogRumService,
useClass: BrowserDatadogRumService
},
{
provide: SubmissionService,
useClass: SubmissionService
Expand Down
8 changes: 7 additions & 1 deletion src/modules/app/server-app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ import { ReferrerService } from '../../app/core/services/referrer.service';
import { ServerReferrerService } from '../../app/core/services/server.referrer.service';
import { MathService } from '../../app/core/shared/math.service';
import { ServerMathService } from '../../app/core/shared/server-math.service';
import { DatadogRumService } from '../../app/shared/datadog-rum/datadog-rum.service';
import { ServerDatadogRumService } from '../../app/shared/datadog-rum/server-datadog-rum.service';

export function createTranslateLoader(transferState: TransferState) {
return new TranslateServerLoader(transferState, 'dist/server/assets/i18n/', '.json');
Expand Down Expand Up @@ -121,7 +123,11 @@ export function createTranslateLoader(transferState: TransferState) {
{
provide: MathService,
useClass: ServerMathService
}
},
{
provide: DatadogRumService,
useClass: ServerDatadogRumService
},
]
})
export class ServerAppModule {
Expand Down

0 comments on commit 484e75e

Please sign in to comment.