Effects
info
This library is deprecated. Use ngneat/effects instead.
Effects can be used to execute side effects (actions, http requests and other operations) upon action events. First, install the package:
npm i @datorama/akita-ng-effects
Next, to register effects, simply run AkitaNgEffects.forRoot()
and register the effect classes:
app.module.ts
import { AkitaNgEffectsModule } from '@datorama/akita-ng-effects';
import { NavigationEffects } from './path/to/effects';
// Only use .forRoot() once in your base module.
@NgModule({
imports: [CommonModule, AkitaNgEffectsModule.forRoot([NavigationEffects])],
})
export class AppModule {}
product.module.ts
import { AkitaNgEffectsModule } from '@datorama/akita-ng-effects';
import { ProductEffects } from './path/to/effects';
// Use .forFeature() on any feature module
@NgModule({
imports: [CommonModule, AkitaNgEffectsModule.forFeature([ProductEffects])],
})
export class FeatureModule {}
Setup Actions
An action always holds a type property and an optional payload.
navigation.actions.ts
import { createAction } from '@datorama/akita-ng-effects';
export const loadMainNavigation = createAction('[Navigation] Load Main Navigation');
export const loadMainNavigationSuccess = createAction(
'[Navigation] Load Main Navigation Success',
props<{ mainNav: { id: number; path: string } }>()
);
Setup Effects
You can use the actions to act upon any action event:
navigation.effect.ts
import { Actions } from '@datorama/akita-ng-effects';
@Injectable()
export class NavigationEffects {
constructor(
private actions$: Actions,
private navigationService: NavigationService,
) {}
loadMainNavigation$ = createEffect(() =>
this.actions$.pipe(
ofType(loadMainNavigation),
switchMap((_) =>
this.navigationService.loadMainNavigation().pipe(
map((mainNav) => loadMainNavigationSuccess({ mainNav }))
)
)
), { dispatch: true }
);
// Or use the decorator
@Effect()
loadMainNavigationSuccess$ = this.actions$.pipe(
ofType(loadMainNavigationSuccess),
map(({ mainNav }) => this.navigationService.updateNavigationTree(mainNav)),
tap((mainRoutes) => this.store.updateNavigation(mainRoutes))
);
}
The parameter dispatch
This parameter dictates if the effect can dispatch an action. Set true
if you want the effect to dispatch an action. Set to false
or omit if the effect should not dispatch any action.
Possible use case
This is one possible use case for an action inside a guard to initialize fetching of a navigation.
You can also use them in components in order to fetch data.
init-route.guard.ts
@Injectable({
providedIn: 'root',
})
export class InitRouterGuard implements CanActivate {
constructor(private actions: Actions, private navigationQuery: NavigationQuery) {}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> {
return this.navigationQuery.isNavInitialized$.pipe(
tap((isInit) => {
if (!isInit) this.actions.dispatch(loadMainNavigation());
}),
filter((isInit) => isInit),
map((_) => true)
);
}
}