diff --git a/apps/example-app/src/app/examples/signals/product-list-paginated-page/product-list-paginated-page-container.component.ts b/apps/example-app/src/app/examples/signals/product-list-paginated-page/product-list-paginated-page-container.component.ts
deleted file mode 100644
index 16fdeaeb..00000000
--- a/apps/example-app/src/app/examples/signals/product-list-paginated-page/product-list-paginated-page-container.component.ts
+++ /dev/null
@@ -1,118 +0,0 @@
-import { AsyncPipe } from '@angular/common';
-import { Component, inject, OnInit } from '@angular/core';
-import { MatButtonModule } from '@angular/material/button';
-import { MatCardModule } from '@angular/material/card';
-import { MatPaginatorModule, PageEvent } from '@angular/material/paginator';
-import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
-import { Sort } from '@ngrx-traits/common';
-
-import { ProductListComponent } from '../../components/product-list/product-list.component';
-import { ProductSearchFormComponent } from '../../components/product-search-form/product-search-form.component';
-import { Product, ProductFilter } from '../../models';
-import { ProductsLocalStore } from './product.store';
-
-@Component({
- selector: 'ngrx-traits-product-list-example-container',
- template: `
-
-
- Product List
-
-
-
- @if (store.productsLoading()) {
-
- } @else {
-
-
-
- }
-
-
-
-
-
- `,
- styles: [
- `
- mat-card-content > mat-spinner {
- margin: 10px auto;
- }
- mat-card-actions mat-spinner {
- display: inline-block;
- margin-right: 5px;
- }
- `,
- ],
- standalone: true,
- imports: [
- MatCardModule,
- ProductSearchFormComponent,
- MatProgressSpinnerModule,
- ProductListComponent,
- MatPaginatorModule,
- MatButtonModule,
- AsyncPipe,
- ],
-})
-export class ProductListPaginatedPageContainerComponent implements OnInit {
- store = inject(ProductsLocalStore);
-
- ngOnInit() {
- this.store.loadProductDetail;
- this.store.productsFilter;
- // this.store.dispatch(ProductActions.loadProductsUsingRouteQueryParams());
- }
-
- select({ id }: Product) {
- this.store.selectProductsEntity({ id });
- }
-
- checkout() {
- this.store.checkout();
- }
-
- filter(filter: ProductFilter | undefined) {
- filter && this.store.filterProductsEntities({ filter });
- }
-
- sort(sort: Sort) {
- this.store.sortProductsEntities({
- sort: { field: sort.active as string, direction: sort.direction },
- });
- }
-
- loadPage($event: PageEvent) {
- this.store.loadProductsPage({ pageIndex: $event.pageIndex });
- }
-}
diff --git a/apps/example-app/src/app/examples/signals/product-list-paginated-page/product.store.ts b/apps/example-app/src/app/examples/signals/product-list-paginated-page/product.store.ts
index 3ce47df0..70deadb7 100644
--- a/apps/example-app/src/app/examples/signals/product-list-paginated-page/product.store.ts
+++ b/apps/example-app/src/app/examples/signals/product-list-paginated-page/product.store.ts
@@ -121,9 +121,11 @@ export const ProductsLocalStore = signalStore(
call: ({ id }: { id: string }) =>
inject(ProductService).getProductDetail(id),
resultProp: 'productDetail',
+ mapPipe: 'switchMap',
},
checkout: () => inject(OrderService).checkout(),
})),
+ withLogger('sdsd'),
);
export const ProductsLocalStore2 = signalStore(
diff --git a/apps/example-app/src/app/examples/signals/product-list-paginated-page/signal-product-list-paginated-page-container.component.ts b/apps/example-app/src/app/examples/signals/product-list-paginated-page/signal-product-list-paginated-page-container.component.ts
index 1e0b1428..ada42f1f 100644
--- a/apps/example-app/src/app/examples/signals/product-list-paginated-page/signal-product-list-paginated-page-container.component.ts
+++ b/apps/example-app/src/app/examples/signals/product-list-paginated-page/signal-product-list-paginated-page-container.component.ts
@@ -1,4 +1,4 @@
-import { AsyncPipe } from '@angular/common';
+import { AsyncPipe, JsonPipe } from '@angular/common';
import { Component, inject, OnInit } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { MatCardModule } from '@angular/material/card';
@@ -6,6 +6,7 @@ import { MatPaginatorModule, PageEvent } from '@angular/material/paginator';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { Sort } from '@ngrx-traits/common';
+import { ProductDetailComponent } from '../../components/product-detail/product-detail.component';
import { ProductListComponent } from '../../components/product-list/product-list.component';
import { ProductSearchFormComponent } from '../../components/product-search-form/product-search-form.component';
import { Product, ProductFilter } from '../../models';
@@ -26,23 +27,32 @@ import { ProductsLocalStore } from './product.store';
@if (store.productsLoading()) {
} @else {
-
-
-
+
}
@@ -83,6 +93,8 @@ import { ProductsLocalStore } from './product.store';
MatPaginatorModule,
MatButtonModule,
AsyncPipe,
+ ProductDetailComponent,
+ JsonPipe,
],
})
export class SignalProductListPaginatedPageContainerComponent
@@ -91,13 +103,13 @@ export class SignalProductListPaginatedPageContainerComponent
store = inject(ProductsLocalStore);
ngOnInit() {
- this.store.productsFilter;
+ // this.store.productDetail;
this.store.loadProductDetail({ id: '12' });
- // this.store.dispatch(ProductActions.loadProductsUsingRouteQueryParams());
}
select({ id }: Product) {
this.store.selectProductsEntity({ id });
+ this.store.loadProductDetail({ id });
}
checkout() {
diff --git a/libs/ngrx-traits/common/src/lib/entities-pagination/entities-pagination.trait.spec.ts b/libs/ngrx-traits/common/src/lib/entities-pagination/entities-pagination.trait.spec.ts
index 168df276..04534db8 100644
--- a/libs/ngrx-traits/common/src/lib/entities-pagination/entities-pagination.trait.spec.ts
+++ b/libs/ngrx-traits/common/src/lib/entities-pagination/entities-pagination.trait.spec.ts
@@ -1,31 +1,31 @@
-import { Actions } from '@ngrx/effects';
-import { createAction, createFeatureSelector } from '@ngrx/store';
+import { TestBed } from '@angular/core/testing';
import {
createEntityFeatureFactory,
FeatureSelectors,
} from '@ngrx-traits/core';
-import { addLoadEntitiesTrait } from '../load-entities';
-import { Todo, TodoFilter } from '../load-entities/load-entities.trait.spec';
+import { Actions } from '@ngrx/effects';
+import { provideMockActions } from '@ngrx/effects/testing';
+import { Dictionary } from '@ngrx/entity';
+import { createAction, createFeatureSelector } from '@ngrx/store';
+import { MockStore, provideMockStore } from '@ngrx/store/testing';
+import { of } from 'rxjs';
+import { first, take, toArray } from 'rxjs/operators';
+
+import { addCrudEntitiesTrait, CrudEntitiesState } from '../crud-entities';
import {
addFilterEntitiesTrait,
FilterEntitiesState,
} from '../filter-entities';
-import { TestBed } from '@angular/core/testing';
-import { provideMockActions } from '@ngrx/effects/testing';
-import { MockStore, provideMockStore } from '@ngrx/store/testing';
-import { addEntitiesPaginationTrait } from './entities-pagination.trait';
+import { ƟFilterEntitiesActions } from '../filter-entities/filter-entities.model.internal';
import { TestState } from '../filter-entities/filter-entities.trait.spec';
+import { addLoadEntitiesTrait } from '../load-entities';
+import { Todo, TodoFilter } from '../load-entities/load-entities.trait.spec';
import { CacheType, PageInfoModel } from './entities-pagination.model';
-import { of } from 'rxjs';
-import { first, take, toArray } from 'rxjs/operators';
-import { addCrudEntitiesTrait, CrudEntitiesState } from '../crud-entities';
-
-import { Dictionary } from '@ngrx/entity';
import {
ƟEntitiesPaginationSelectors,
ƟPaginationActions,
} from './entities-pagination.model.internal';
-import { ƟFilterEntitiesActions } from '../filter-entities/filter-entities.model.internal';
+import { addEntitiesPaginationTrait } from './entities-pagination.trait';
export interface PaginationTestState
extends TestState,
@@ -43,7 +43,7 @@ describe('Pagination Test', () => {
function initWithFilterAndPagination(
cacheType: CacheType = 'full',
- remoteFilter = true
+ remoteFilter = true,
) {
const featureSelector = createFeatureSelector('test');
const traits = createEntityFeatureFactory(
@@ -58,7 +58,7 @@ describe('Pagination Test', () => {
?.toLowerCase()
.includes(filter.content.toLowerCase()),
}),
- addEntitiesPaginationTrait({ cacheType, pageSize: 20 })
+ addEntitiesPaginationTrait({ cacheType, pageSize: 20 }),
)({
actionsGroupKey: 'test',
featureSelector: featureSelector,
@@ -80,7 +80,7 @@ describe('Pagination Test', () => {
{ entityName: 'entity', entitiesName: 'entities' },
addLoadEntitiesTrait(),
addCrudEntitiesTrait(),
- addEntitiesPaginationTrait({ cacheType, pageSize: 20 })
+ addEntitiesPaginationTrait({ cacheType, pageSize: 20 }),
)({
actionsGroupKey: 'test',
featureSelector: featureSelector,
@@ -101,7 +101,7 @@ describe('Pagination Test', () => {
currentPage: number,
start: number,
end: number,
- total = todos.length
+ total = todos.length,
): TestState {
return {
...state,
@@ -126,7 +126,7 @@ describe('Pagination Test', () => {
const state = reducer(
initialState,
- actions.loadEntitiesPage({ index: 3 })
+ actions.loadEntitiesPage({ index: 3 }),
);
expect(state).toEqual({
@@ -145,7 +145,7 @@ describe('Pagination Test', () => {
const a = actions as unknown as ƟPaginationActions;
const state = reducer(
initialState,
- a.setEntitiesRequestPage({ index: 2 })
+ a.setEntitiesRequestPage({ index: 2 }),
);
expect(state).toEqual({
@@ -214,7 +214,7 @@ describe('Pagination Test', () => {
actions.loadEntitiesSuccess({
entities: todos,
total: todos.length,
- })
+ }),
);
// reset(getTimeSpy);
expect(state).toEqual(pageState(state, todos, 0, 0, 135));
@@ -231,14 +231,14 @@ describe('Pagination Test', () => {
initialState,
actions.loadEntitiesPage({
index: 0,
- })
+ }),
);
state = reducer(
state,
actions.loadEntitiesSuccess({
entities: first3pages,
total: todos.length,
- })
+ }),
);
expect(state).toEqual(pageState(state, first3pages, 0, 0, 60));
@@ -249,14 +249,14 @@ describe('Pagination Test', () => {
state,
actions.loadEntitiesPage({
index: 3,
- })
+ }),
);
state = reducer(
state,
actions.loadEntitiesSuccess({
entities: next3pages,
total: todos.length,
- })
+ }),
);
expect(state).toEqual(pageState(state, next3pages, 3, 60, 120));
@@ -266,14 +266,14 @@ describe('Pagination Test', () => {
state,
actions.loadEntitiesPage({
index: 6,
- })
+ }),
);
state = reducer(
state,
actions.loadEntitiesSuccess({
entities: last3pages,
total: todos.length,
- })
+ }),
);
expect(state).toEqual(pageState(state, last3pages, 6, 120, 135));
@@ -283,14 +283,14 @@ describe('Pagination Test', () => {
state,
actions.loadEntitiesPage({
index: 1,
- })
+ }),
);
state = reducer(
state,
actions.loadEntitiesSuccess({
entities: page2To4,
total: todos.length,
- })
+ }),
);
expect(state).toEqual(pageState(state, page2To4, 1, 20, 80));
});
@@ -306,14 +306,14 @@ describe('Pagination Test', () => {
initialState,
actions.loadEntitiesPage({
index: 0,
- })
+ }),
);
state = reducer(
state,
actions.loadEntitiesSuccess({
entities: first3pages,
total: todos.length,
- })
+ }),
);
expect(state).toEqual(pageState(state, first3pages, 0, 0, 60));
@@ -324,17 +324,17 @@ describe('Pagination Test', () => {
state,
actions.loadEntitiesPage({
index: 3,
- })
+ }),
);
state = reducer(
state,
actions.loadEntitiesSuccess({
entities: next3pages,
total: todos.length,
- })
+ }),
);
expect(state).toEqual(
- pageState(state, [...first3pages, ...next3pages], 3, 0, 120)
+ pageState(state, [...first3pages, ...next3pages], 3, 0, 120),
);
// check last 3 pages
@@ -343,14 +343,14 @@ describe('Pagination Test', () => {
state,
actions.loadEntitiesPage({
index: 6,
- })
+ }),
);
state = reducer(
state,
actions.loadEntitiesSuccess({
entities: last3pages,
total: todos.length,
- })
+ }),
);
expect(state).toEqual(
pageState(
@@ -358,8 +358,8 @@ describe('Pagination Test', () => {
[...first3pages, ...next3pages, ...last3pages],
6,
0,
- 135
- )
+ 135,
+ ),
);
});
@@ -374,30 +374,30 @@ describe('Pagination Test', () => {
initialState,
actions.loadEntitiesPage({
index: 0,
- })
+ }),
);
state = reducer(
state,
actions.loadEntitiesSuccess({
entities: first3pages,
total: 60,
- })
+ }),
);
state = reducer(
state,
actions.loadEntitiesPage({
index: 2,
- })
+ }),
);
state = reducer(
state,
(
actions as unknown as ƟFilterEntitiesActions
- ).storeEntitiesFilter({ filters: { content: '10' } })
+ ).storeEntitiesFilter({ filters: { content: '10' } }),
);
expect(
- selectors.selectEntitiesCurrentPageInfo.projector(state)
+ selectors.selectEntitiesCurrentPageInfo.projector(state),
).toEqual({
pageIndex: 0,
total: 1,
@@ -418,34 +418,34 @@ describe('Pagination Test', () => {
initialState,
actions.loadEntitiesPage({
index: 0,
- })
+ }),
);
state = reducer(
state,
actions.loadEntitiesSuccess({
entities: first3pages,
total: todos.length,
- })
+ }),
);
state = reducer(
state,
actions.loadEntitiesPage({
index: 2,
- })
+ }),
);
state = reducer(
state,
(
actions as unknown as ƟFilterEntitiesActions
- ).storeEntitiesFilter({ filters: { content: 'something' } })
+ ).storeEntitiesFilter({ filters: { content: 'something' } }),
);
state = reducer(
state,
actions.loadEntitiesSuccess({
entities: todos.slice(40, 60),
total: 20,
- })
+ }),
);
expect(state).toEqual({
...state,
@@ -490,22 +490,22 @@ describe('Pagination Test', () => {
initialState,
actions.loadEntitiesPage({
index: 0,
- })
+ }),
);
state = reducer(
state,
actions.loadEntitiesSuccess({
entities: todos,
total: todos.length,
- })
+ }),
);
const resultState = reducer(
state,
actions.addEntities(
{ id: 123123, content: 'some' },
- { id: 324324, content: 'some2' }
- )
+ { id: 324324, content: 'some2' },
+ ),
);
expect(resultState.pagination).toEqual({
@@ -521,14 +521,14 @@ describe('Pagination Test', () => {
initialState,
actions.loadEntitiesPage({
index: 0,
- })
+ }),
);
state = reducer(
state,
actions.loadEntitiesSuccess({
entities: todos,
total: todos.length,
- })
+ }),
);
const resultState = reducer(state, actions.removeEntities(1, 2));
@@ -549,43 +549,43 @@ describe('Pagination Test', () => {
let state = pageState(initialState, todos, 2, 0, 75);
// if no page return currentPage
expect(selectors.selectEntitiesCurrentPageList.projector(state)).toEqual(
- todos.slice(40, 60)
+ todos.slice(40, 60),
);
state = reducer(
state,
actions.loadEntitiesPage({
index: 0,
- })
+ }),
);
expect(selectors.selectEntitiesCurrentPageList.projector(state)).toEqual(
- todos.slice(0, 20)
+ todos.slice(0, 20),
);
state = reducer(
state,
actions.loadEntitiesPage({
index: 1,
- })
+ }),
);
expect(selectors.selectEntitiesCurrentPageList.projector(state)).toEqual(
- todos.slice(20, 40)
+ todos.slice(20, 40),
);
state = reducer(
state,
actions.loadEntitiesPage({
index: 2,
- })
+ }),
);
expect(selectors.selectEntitiesCurrentPageList.projector(state)).toEqual(
- todos.slice(40, 60)
+ todos.slice(40, 60),
);
state = reducer(
state,
actions.loadEntitiesPage({
index: 3,
- })
+ }),
);
expect(selectors.selectEntitiesCurrentPageList.projector(state)).toEqual(
- todos.slice(60, 75)
+ todos.slice(60, 75),
);
});
@@ -604,83 +604,83 @@ describe('Pagination Test', () => {
let state = pageState(initialState, todos, 2, 0, 60);
// using currentPage
expect(selectors.isEntitiesCurrentPageInCache.projector(state)).toEqual(
- true
+ true,
);
expect(selectors.isEntitiesNextPageInCache.projector(state)).toEqual(
- false
+ false,
);
state = reducer(
state,
actions.loadEntitiesPage({
index: 0,
- })
+ }),
);
// using explicit page
expect(selectors.isEntitiesCurrentPageInCache.projector(state)).toEqual(
- true
+ true,
);
expect(selectors.isEntitiesNextPageInCache.projector(state)).toEqual(
- true
+ true,
);
state = reducer(
state,
actions.loadEntitiesPage({
index: 1,
- })
+ }),
);
expect(selectors.isEntitiesCurrentPageInCache.projector(state)).toEqual(
- true
+ true,
);
expect(selectors.isEntitiesNextPageInCache.projector(state)).toEqual(
- true
+ true,
);
state = reducer(
state,
actions.loadEntitiesPage({
index: 2,
- })
+ }),
);
expect(selectors.isEntitiesCurrentPageInCache.projector(state)).toEqual(
- true
+ true,
);
expect(selectors.isEntitiesNextPageInCache.projector(state)).toEqual(
- false
+ false,
);
state = reducer(
state,
actions.loadEntitiesPage({
index: 3,
- })
+ }),
);
expect(selectors.isEntitiesCurrentPageInCache.projector(state)).toEqual(
- false
+ false,
);
expect(selectors.isEntitiesNextPageInCache.projector(state)).toEqual(
- false
+ false,
);
state = reducer(
state,
actions.loadEntitiesPage({
index: 4,
- })
+ }),
);
expect(selectors.isEntitiesCurrentPageInCache.projector(state)).toEqual(
- false
+ false,
);
expect(selectors.isEntitiesNextPageInCache.projector(state)).toEqual(
- false
+ false,
);
state = reducer(
state,
actions.loadEntitiesPage({
index: 5,
- })
+ }),
);
expect(selectors.isEntitiesCurrentPageInCache.projector(state)).toEqual(
- false
+ false,
);
expect(selectors.isEntitiesNextPageInCache.projector(state)).toEqual(
- false
+ false,
);
});
@@ -704,12 +704,12 @@ describe('Pagination Test', () => {
state,
actions.loadEntitiesPage({
index: 0,
- })
+ }),
);
expect(
selectors.selectEntitiesCurrentPage.projector(
- pageState(initialState, todos.slice(0, 75), 1, 0, 75, 75)
- )
+ pageState(initialState, todos.slice(0, 75), 1, 0, 75, 75),
+ ),
).toEqual({
entities: todos.slice(20, 40),
isLoading: false,
@@ -727,8 +727,8 @@ describe('Pagination Test', () => {
const { selectors, initialState } = initWithFilterAndPagination();
expect(
selectors.selectEntitiesCurrentPageInfo.projector(
- pageState(initialState, todos.slice(0, 75), 0, 0, 75, 75)
- )
+ pageState(initialState, todos.slice(0, 75), 0, 0, 75, 75),
+ ),
).toEqual({
pageIndex: 0,
total: 75,
@@ -740,8 +740,8 @@ describe('Pagination Test', () => {
});
expect(
selectors.selectEntitiesCurrentPageInfo.projector(
- pageState(initialState, todos.slice(0, 75), 1, 0, 75, 75)
- )
+ pageState(initialState, todos.slice(0, 75), 1, 0, 75, 75),
+ ),
).toEqual({
pageIndex: 1,
total: 75,
@@ -753,8 +753,8 @@ describe('Pagination Test', () => {
});
expect(
selectors.selectEntitiesCurrentPageInfo.projector(
- pageState(initialState, todos.slice(0, 75), 2, 0, 75, 75)
- )
+ pageState(initialState, todos.slice(0, 75), 2, 0, 75, 75),
+ ),
).toEqual({
pageIndex: 2,
total: 75,
@@ -766,8 +766,8 @@ describe('Pagination Test', () => {
});
expect(
selectors.selectEntitiesCurrentPageInfo.projector(
- pageState(initialState, todos.slice(0, 75), 3, 0, 75, 75)
- )
+ pageState(initialState, todos.slice(0, 75), 3, 0, 75, 75),
+ ),
).toEqual({
pageIndex: 3,
total: 75,
@@ -782,7 +782,7 @@ describe('Pagination Test', () => {
it('selectEntitiesPagedRequest ', () => {
const { selectors, initialState } = initWithFilterAndPagination();
expect(
- selectors.selectEntitiesPagedRequest.projector(initialState)
+ selectors.selectEntitiesPagedRequest.projector(initialState),
).toEqual({
page: 0,
size: 60,
@@ -795,13 +795,13 @@ describe('Pagination Test', () => {
3,
0,
75,
- 75
+ 75,
);
expect(
selectors.selectEntitiesPagedRequest.projector({
...testState,
pagination: { ...testState.pagination, requestPage: 3 },
- })
+ }),
).toEqual({
page: 3,
size: 60,
@@ -818,14 +818,14 @@ describe('Pagination Test', () => {
2,
0,
75,
- 75
+ 75,
);
expect(
selectors.isLoadingEntitiesCurrentPage.projector({
...testState,
status: 'loading',
pagination: { ...testState.pagination, requestPage: 3 },
- })
+ }),
).toEqual(false);
});
@@ -838,14 +838,14 @@ describe('Pagination Test', () => {
3,
0,
75,
- 75
+ 75,
);
expect(
selectors.isLoadingEntitiesCurrentPage.projector({
...testState,
status: 'loading',
pagination: { ...testState.pagination, requestPage: 3 },
- })
+ }),
).toEqual(true);
});
@@ -858,14 +858,14 @@ describe('Pagination Test', () => {
3,
0,
75,
- 75
+ 75,
);
expect(
selectors.isLoadingEntitiesCurrentPage.projector({
...testState,
status: 'success',
pagination: { ...testState.pagination, requestPage: 3 },
- })
+ }),
).toEqual(false);
});
});
@@ -976,7 +976,7 @@ describe('Pagination Test', () => {
actions$ = of(actions.loadEntitiesPage({ index: 1 }));
mockStore.overrideSelector(
selectors.isEntitiesCurrentPageInCache,
- true
+ true,
);
const action = await effects.loadPage$.pipe(first()).toPromise();
expect(action).toEqual(actions.loadEntitiesPageSuccess());
@@ -996,7 +996,7 @@ describe('Pagination Test', () => {
actions$ = of(actions.loadEntitiesPage({ index: 1 }));
mockStore.overrideSelector(
selectors.isEntitiesCurrentPageInCache,
- false
+ false,
);
const action = await effects.loadPage$.pipe(first()).toPromise();
expect(action).toEqual(actions.loadEntities());
@@ -1016,7 +1016,7 @@ describe('Pagination Test', () => {
actions$ = of(actions.loadEntitiesPage({ index: 1, forceLoad: true }));
mockStore.overrideSelector(
selectors.isEntitiesCurrentPageInCache,
- true
+ true,
);
const action = await effects.loadPage$.pipe(first()).toPromise();
expect(action).toEqual(actions.loadEntities());
@@ -1028,7 +1028,7 @@ describe('Pagination Test', () => {
cacheType: CacheType,
total: number | null = 10 * 20,
hasNext = true,
- isEntitiesPageInCache = false
+ isEntitiesPageInCache = false,
) {
const {
effects,
@@ -1040,11 +1040,10 @@ describe('Pagination Test', () => {
TestState,
ƟEntitiesPaginationSelectors
>;
- console.log(s);
actions$ = of(actions.loadEntitiesPageSuccess());
mockStore.overrideSelector(
selectors.isEntitiesNextPageInCache,
- isEntitiesPageInCache
+ isEntitiesPageInCache,
);
mockStore.overrideSelector(selectors.selectEntitiesCurrentPageInfo, {
hasNext,
diff --git a/libs/ngrx-traits/signals/src/lib/with-call-status/with-call-status.ts b/libs/ngrx-traits/signals/src/lib/with-call-status/with-call-status.ts
index eec58ee5..9156806b 100644
--- a/libs/ngrx-traits/signals/src/lib/with-call-status/with-call-status.ts
+++ b/libs/ngrx-traits/signals/src/lib/with-call-status/with-call-status.ts
@@ -47,14 +47,6 @@ export type NamedCallStateMethods = {
[K in Prop as `set${Capitalize}Error`]: () => void;
};
-export function setLoading(): { callState: 'loading' } {
- return { callState: 'loading' };
-}
-
-export function setLoaded(): { callState: 'loaded' } {
- return { callState: 'loaded' };
-}
-
export function withCallStatus(config?: {
initialValue?: CallStatus;
}): SignalStoreFeature<
@@ -100,12 +92,10 @@ export function withCallStatus({
return {
[loadingKey]: computed(() => {
- console.log('callState()', callState());
return callState() === 'loading';
}),
[loadedKey]: computed(() => callState() === 'loaded'),
[errorKey]: computed(() => {
- // TODO should we handle storing the error
const v = callState();
return typeof v === 'object' ? v.error : null;
}),
diff --git a/libs/ngrx-traits/signals/src/lib/with-calls/with-calls.ts b/libs/ngrx-traits/signals/src/lib/with-calls/with-calls.ts
index 24b83c74..03c12a4a 100644
--- a/libs/ngrx-traits/signals/src/lib/with-calls/with-calls.ts
+++ b/libs/ngrx-traits/signals/src/lib/with-calls/with-calls.ts
@@ -14,13 +14,14 @@ import {
withState,
} from '@ngrx/signals';
import { rxMethod } from '@ngrx/signals/rxjs-interop';
-import {
+import type {
SignalStoreFeatureResult,
SignalStoreSlices,
} from '@ngrx/signals/src/signal-store-models';
-import { StateSignal } from '@ngrx/signals/src/state-signal';
+import type { StateSignal } from '@ngrx/signals/src/state-signal';
import {
catchError,
+ concatMap,
exhaustMap,
first,
from,
@@ -28,13 +29,13 @@ import {
Observable,
of,
pipe,
+ switchMap,
} from 'rxjs';
import {
CallStatus,
NamedCallState,
NamedCallStateComputed,
- NamedCallStateMethods,
} from '../with-call-status/with-call-status';
import { getWithCallStatusKeys } from '../with-call-status/with-call-status.util';
import { getWithCallKeys } from './with-calls.util';
@@ -48,7 +49,8 @@ type CallConfig<
PropName extends string = string,
> = {
call: Call;
- resultProp: PropName;
+ resultProp?: PropName;
+ mapPipe?: 'switchMap' | 'concatMap' | 'exhaustMap';
};
export type ExtractCallResultType =
@@ -74,8 +76,10 @@ export function withCalls<
Input & {
state: NamedCallState & {
[K in keyof Calls as Calls[K] extends CallConfig
- ? Calls[K]['resultProp'] & string
- : `${K & string}Data`]?: ExtractCallResultType;
+ ? Calls[K]['resultProp'] extends string
+ ? Calls[K]['resultProp']
+ : `${K & string}Result`
+ : `${K & string}Result`]?: ExtractCallResultType;
};
signals: NamedCallStateComputed;
methods: {
@@ -91,10 +95,17 @@ export function withCalls<
} as SignalStoreSlices &
Input['signals'] &
Input['methods']);
- const callsState = Object.keys(calls).reduce(
- (acc, callName) => {
+ const callsState = Object.entries(calls).reduce(
+ (acc, [callName, call]) => {
const { callStatusKey } = getWithCallStatusKeys({ prop: callName });
acc[callStatusKey] = 'init';
+ const { resultPropKey } = getWithCallKeys({
+ callName,
+ resultProp: isCallConfig(call)
+ ? call.resultProp
+ : `${callName}Result`,
+ });
+ acc[resultPropKey] = undefined;
return acc;
},
{} as Record,
@@ -135,8 +146,13 @@ export function withCalls<
callName,
resultProp: isCallConfig(call)
? call.resultProp
- : `${callName}Data`,
+ : `${callName}Result`,
});
+
+ const mapPipe =
+ isCallConfig(call) && call.mapPipe
+ ? mapPipes[call.mapPipe]
+ : exhaustMap;
const setLoading = () =>
patchState(store, {
[callStatusKey]: 'loading',
@@ -157,13 +173,13 @@ export function withCalls<
patchState(store, {
[callStatusKey]: 'loaded',
} as StateSignal