Skip to content

Commit

Permalink
feat(local-traits): allow effects on traitlocal classes
Browse files Browse the repository at this point in the history
simplify the flow to create local traits by allowing effects inside the traitlocal services
  • Loading branch information
Gabriel Guerrero authored and gabrielguerrero committed Mar 31, 2022
1 parent eaf932e commit e386d27
Show file tree
Hide file tree
Showing 7 changed files with 305 additions and 209 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ import { ProductsLocalTraits } from './products.traits';
})
export class ProductSelectDialogComponent implements OnInit {
data$ = combineLatest([
this.store.select(this.localTraits.selectors.selectProductsList),
this.store.select(this.localTraits.selectors.isProductsLoading),
this.store.select(this.localTraits.selectors.selectProductSelected),
this.store.select(this.localTraits.localSelectors.selectProductsList),
this.store.select(this.localTraits.localSelectors.isProductsLoading),
this.store.select(this.localTraits.localSelectors.selectProductSelected),
]).pipe(
map(([products, isLoading, selectedProduct]) => ({
products,
Expand All @@ -61,17 +61,19 @@ export class ProductSelectDialogComponent implements OnInit {
constructor(private store: Store, private localTraits: ProductsLocalTraits) {}

ngOnInit() {
this.store.dispatch(this.localTraits.actions.loadProducts());
this.store.dispatch(this.localTraits.localActions.loadProducts());
}

select({ id }: Product) {
this.store.dispatch(this.localTraits.actions.selectProduct({ id }));
this.store.dispatch(this.localTraits.localActions.selectProduct({ id }));
}

filter(filters: ProductFilter) {
this.store.dispatch(this.localTraits.actions.filterProducts({ filters }));
this.store.dispatch(
this.localTraits.localActions.filterProducts({ filters })
);
}
sort(sort: Sort<Product>) {
this.store.dispatch(this.localTraits.actions.sortProducts(sort));
this.store.dispatch(this.localTraits.localActions.sortProducts(sort));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,16 @@ import {
} from 'ngrx-traits/traits';
import { Product, ProductFilter } from '../../../models';
import {
buildLocalTraits,
createEntityFeatureFactory,
LocalTraitsConfig,
TraitEffect,
TraitLocalEffectsFactory,
TraitsLocalStore,
} from 'ngrx-traits';
import { Injectable } from '@angular/core';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { Injectable, Injector } from '@angular/core';
import { createEffect, ofType } from '@ngrx/effects';
import { catchError, map, switchMap, tap } from 'rxjs/operators';
import { of } from 'rxjs';
import { ProductService } from '../../../services/product.service';
import { Store } from '@ngrx/store';

const productFeatureFactory = createEntityFeatureFactory(
{ entityName: 'product' },
Expand All @@ -33,46 +31,34 @@ const productFeatureFactory = createEntityFeatureFactory(
})
);

const productsEffect: TraitLocalEffectsFactory<typeof productFeatureFactory> = (
allActions
) => {
@Injectable()
class ProductsEffects extends TraitEffect {
loadProducts$ = createEffect(() =>
this.actions$.pipe(
ofType(allActions.loadProducts),
switchMap(() =>
//call your service to get the products data
this.productService.getProducts().pipe(
map((res) =>
allActions.loadProductsSuccess({ entities: res.resultList })
),
catchError(() => of(allActions.loadProductsFail()))
)
@Injectable()
export class ProductsLocalTraits extends TraitsLocalStore<
typeof productFeatureFactory
> {
loadProducts$ = createEffect(() =>
this.actions$.pipe(
ofType(this.localActions.loadProducts),
switchMap(() =>
//call your service to get the products data
this.productService.getProducts().pipe(
map((res) =>
this.localActions.loadProductsSuccess({ entities: res.resultList })
),
catchError(() => of(this.localActions.loadProductsFail()))
)
)
);
)
);

constructor(
actions$: Actions,
store: Store,
private productService: ProductService
) {
super(actions$, store);
}
constructor(injector: Injector, private productService: ProductService) {
super(injector);
this.traits.addEffects(this);
}
return ProductsEffects;
};

@Injectable()
export class ProductsLocalTraits extends TraitsLocalStore<
typeof productFeatureFactory
> {
setup(): LocalTraitsConfig<typeof productFeatureFactory> {
return {
componentName: 'ProductsPickerComponent',
traitsFactory: productFeatureFactory,
effectFactory: productsEffect,
};
}
}
116 changes: 96 additions & 20 deletions libs/ngrx-traits/src/lib/create-entity-feature.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
import { TestBed } from '@angular/core/testing';
import { createEffect, EffectsModule, ofType } from '@ngrx/effects';
import { first, mapTo } from 'rxjs/operators';
import { Injectable } from '@angular/core';
import { Injectable, Injector } from '@angular/core';
import { LocalTraitsConfig, TraitsLocalStore } from './local-store';

export interface TodoFilter {
Expand Down Expand Up @@ -78,6 +78,24 @@ const productMixedFactory = mixEntityFeatures({

@Injectable()
class ProductTraitLocal extends TraitsLocalStore<typeof productFeatureFactory> {
loadEntities$ = createEffect(() => {
return this.actions$.pipe(
ofType(this.localActions.loadProducts),
mapTo(
this.localActions.loadProductsSuccess({
entities: [
{ id: 1, name: 'name', description: 'description', price: 123 },
],
})
)
);
});

constructor(injector: Injector) {
super(injector);
this.traits.addEffects(this);
}

setup(): LocalTraitsConfig<typeof productFeatureFactory> {
return {
componentName: 'ProductTestComponent',
Expand All @@ -90,6 +108,24 @@ class ProductTraitLocal extends TraitsLocalStore<typeof productFeatureFactory> {
class ProductCombinedTraitLocal extends TraitsLocalStore<
typeof productCombinedFactory
> {
loadEntities$ = createEffect(() => {
return this.actions$.pipe(
ofType(this.localActions.products.loadProducts),
mapTo(
this.localActions.products.loadProductsSuccess({
entities: [
{ id: 1, name: 'name', description: 'description', price: 123 },
],
})
)
);
});

constructor(injector: Injector) {
super(injector);
this.traits.addEffects(this);
}

setup(): LocalTraitsConfig<typeof productCombinedFactory> {
return {
componentName: 'ProductCombinedTestComponent',
Expand All @@ -102,6 +138,24 @@ class ProductCombinedTraitLocal extends TraitsLocalStore<
class ProductMixedTraitLocal extends TraitsLocalStore<
typeof productMixedFactory
> {
loadEntities$ = createEffect(() => {
return this.actions$.pipe(
ofType(this.localActions.loadProducts),
mapTo(
this.localActions.loadProductsSuccess({
entities: [
{ id: 1, name: 'name', description: 'description', price: 123 },
],
})
)
);
});

constructor(injector: Injector) {
super(injector);
this.traits.addEffects(this);
}

setup(): LocalTraitsConfig<typeof productMixedFactory> {
return {
componentName: 'ProductMixedTestComponent',
Expand All @@ -114,6 +168,24 @@ class ProductMixedTraitLocal extends TraitsLocalStore<
class ProductAddEntityPropertiesTraitLocal extends TraitsLocalStore<
typeof productAddEntityPropertiesFactory
> {
loadEntities$ = createEffect(() => {
return this.actions$.pipe(
ofType(this.localActions.loadProducts),
mapTo(
this.localActions.loadProductsSuccess({
entities: [
{ id: 1, name: 'name', description: 'description', price: 123 },
],
})
)
);
});

constructor(injector: Injector) {
super(injector);
this.traits.addEffects(this);
}

setup(): LocalTraitsConfig<typeof productAddEntityPropertiesFactory> {
return {
componentName: 'ProductAddEntityPropertiesTestComponent',
Expand Down Expand Up @@ -395,33 +467,37 @@ describe('Ngrx-Traits Integration Test', () => {
describe('single feature trait local', () => {
it('test some action and selectors in products ', async () => {
const { localTrait, store } = initTraitLocal();
await basicProductTest(localTrait.actions, localTrait.selectors, store);
await basicProductTest(
localTrait.localActions,
localTrait.localSelectors,
store
);
});

describe('test combined trait local', () => {
it('test some action and selectors in products ', async () => {
const { localTrait, store } = initCombinedTraitLocal();
await basicProductTest(
localTrait.actions.products,
localTrait.selectors.products,
localTrait.localActions.products,
localTrait.localSelectors.products,
store
);
});

it('test some action and selectors in productOrders ', async () => {
const { localTrait, store } = initCombinedTraitLocal();
await basicProductOrdersTest(
localTrait.actions.productOrders,
localTrait.selectors.productOrders,
localTrait.localActions.productOrders,
localTrait.localSelectors.productOrders,
store
);
});

it('test some action and selectors in clients ', async () => {
const { localTrait, store } = initCombinedTraitLocal();
await basicClientsTest(
localTrait.actions.clients,
localTrait.selectors.clients,
localTrait.localActions.clients,
localTrait.localSelectors.clients,
store
);
});
Expand All @@ -431,26 +507,26 @@ describe('Ngrx-Traits Integration Test', () => {
it('test some action and selectors in products ', async () => {
const { localTrait, store } = initMixedTraitLocal();
await basicProductTest(
localTrait.actions,
localTrait.selectors,
localTrait.localActions,
localTrait.localSelectors,
store
);
});

it('test some action and selectors in productOrders ', async () => {
const { localTrait, store } = initMixedTraitLocal();
await basicProductOrdersTest(
localTrait.actions,
localTrait.selectors,
localTrait.localActions,
localTrait.localSelectors,
store
);
});

it('test some action and selectors in clients ', async () => {
const { localTrait, store } = initMixedTraitLocal();
await basicClientsTest(
localTrait.actions,
localTrait.selectors,
localTrait.localActions,
localTrait.localSelectors,
store
);
});
Expand All @@ -460,26 +536,26 @@ describe('Ngrx-Traits Integration Test', () => {
it('test some action and selectors in products ', async () => {
const { localTrait, store } = initAddEntityProperties();
await basicProductTest(
localTrait.actions,
localTrait.selectors,
localTrait.localActions,
localTrait.localSelectors,
store
);
});

it('test some action and selectors in productOrders ', async () => {
const { localTrait, store } = initAddEntityProperties();
await basicProductOrdersTest(
localTrait.actions.productOrders,
localTrait.selectors.productOrders,
localTrait.localActions.productOrders,
localTrait.localSelectors.productOrders,
store
);
});

it('test some action and selectors in clients ', async () => {
const { localTrait, store } = initAddEntityProperties();
await basicClientsTest(
localTrait.actions.clients,
localTrait.selectors.clients,
localTrait.localActions.clients,
localTrait.localSelectors.clients,
store
);
});
Expand Down
Loading

0 comments on commit e386d27

Please sign in to comment.