Skip to content

Commit fcc04e4

Browse files
authored
feat(product): transfer in-memory state when hydrating backend (#4148)
1 parent e57e807 commit fcc04e4

3 files changed

Lines changed: 103 additions & 3 deletions

File tree

libs/product/driver/in-memory/src/backend/product.service.spec.ts

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
import {
2+
PLATFORM_ID,
3+
TransferState,
4+
} from '@angular/core';
15
import { TestBed } from '@angular/core/testing';
26

37
import {
@@ -7,6 +11,7 @@ import {
711
} from '@daffodil/product/testing';
812

913
import { DaffInMemoryBackendProductService } from './product.service';
14+
import { TRANSFER_STATE_KEY } from './transfer-state-key';
1015

1116
describe('Driver | InMemory | Product | DaffInMemoryBackendProductService', () => {
1217
let productTestingService;
@@ -26,6 +31,85 @@ describe('Driver | InMemory | Product | DaffInMemoryBackendProductService', () =
2631
expect(productTestingService).toBeTruthy();
2732
});
2833

34+
describe('transferring state from the server to the browser', () => {
35+
describe('on browser platform', () => {
36+
let transferState: TransferState;
37+
let mockProducts;
38+
39+
beforeEach(() => {
40+
mockProducts = [
41+
{ id: '1', url: '/product-1.html', name: 'Product 1' },
42+
{ id: '2', url: '/product-2.html', name: 'Product 2' },
43+
];
44+
45+
TestBed.resetTestingModule();
46+
TestBed.configureTestingModule({
47+
providers: [
48+
DaffInMemoryBackendProductService,
49+
provideDaffProductExtraFactoryTypes(DaffProductFactory),
50+
{ provide: PLATFORM_ID, useValue: 'browser' },
51+
],
52+
});
53+
54+
transferState = TestBed.inject(TransferState);
55+
transferState.set(TRANSFER_STATE_KEY, mockProducts);
56+
57+
productTestingService = TestBed.inject(DaffInMemoryBackendProductService);
58+
});
59+
60+
it('should load products from transfer state', () => {
61+
expect(productTestingService.products).toEqual(mockProducts);
62+
});
63+
64+
it('should not create new products', () => {
65+
expect(productTestingService.products.length).toEqual(2);
66+
});
67+
});
68+
69+
describe('on browser platform without transfer state', () => {
70+
beforeEach(() => {
71+
TestBed.resetTestingModule();
72+
TestBed.configureTestingModule({
73+
providers: [
74+
DaffInMemoryBackendProductService,
75+
provideDaffProductExtraFactoryTypes(DaffProductFactory),
76+
{ provide: PLATFORM_ID, useValue: 'browser' },
77+
],
78+
});
79+
80+
productTestingService = TestBed.inject(DaffInMemoryBackendProductService);
81+
});
82+
83+
it('should create default products from factory', () => {
84+
expect(productTestingService.products.length).toEqual(35);
85+
});
86+
});
87+
88+
describe('on server platform', () => {
89+
let transferState: TransferState;
90+
91+
beforeEach(() => {
92+
TestBed.resetTestingModule();
93+
TestBed.configureTestingModule({
94+
providers: [
95+
DaffInMemoryBackendProductService,
96+
provideDaffProductExtraFactoryTypes(DaffProductFactory),
97+
{ provide: PLATFORM_ID, useValue: 'server' },
98+
],
99+
});
100+
101+
transferState = TestBed.inject(TransferState);
102+
productTestingService = TestBed.inject(DaffInMemoryBackendProductService);
103+
});
104+
105+
it('should set products in transfer state', () => {
106+
const transferStateData = transferState.get(TRANSFER_STATE_KEY, null);
107+
expect(transferStateData).toBeTruthy();
108+
expect(Array.isArray(transferStateData)).toBe(true);
109+
});
110+
});
111+
});
112+
29113
describe('createDb', () => {
30114
let result;
31115

libs/product/driver/in-memory/src/backend/product.service.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1+
import { isPlatformBrowser } from '@angular/common';
12
import {
23
inject,
34
Injectable,
5+
PLATFORM_ID,
6+
TransferState,
47
} from '@angular/core';
58
import {
69
InMemoryDbService,
@@ -16,6 +19,7 @@ import { DaffProduct } from '@daffodil/product';
1619
import { DaffProductExtensionFactory } from '@daffodil/product/testing';
1720

1821
import { DAFF_PRODUCT_IN_MEMORY_COLLECTION_NAME } from '../collection-name.const';
22+
import { TRANSFER_STATE_KEY } from './transfer-state-key';
1923
/**
2024
* An in-memory service that stubs out the backend services for getting products.
2125
*
@@ -38,10 +42,17 @@ export class DaffInMemoryBackendProductService implements InMemoryDbService, Daf
3842
return this._products;
3943
};
4044

41-
productFactory = inject(DaffProductExtensionFactory);
42-
4345
constructor(){
44-
this._products = this.productFactory.createMany(35);
46+
const transferState = inject(TransferState);
47+
const platform = inject(PLATFORM_ID);
48+
const productFactory = inject(DaffProductExtensionFactory);
49+
50+
if(isPlatformBrowser(platform)) {
51+
this._products = transferState.get(TRANSFER_STATE_KEY, productFactory.createMany(35));
52+
} else {
53+
this._products = productFactory.createMany(35);
54+
transferState.set(TRANSFER_STATE_KEY, this._products);
55+
}
4556
}
4657

4758
/**
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { makeStateKey } from '@angular/core';
2+
3+
import { DaffProduct } from '@daffodil/product';
4+
5+
export const TRANSFER_STATE_KEY = makeStateKey<DaffProduct[]>('DAFF_PRODUCTS_INMEMORY_DATA');

0 commit comments

Comments
 (0)