已引入必要模块且无循环依赖,NgRx Effects中Actions为何无法注入?
问题
开发协作文档编辑器应用时,使用NgRx Effects实现基于状态变更触发的逻辑,已安装相关依赖并在app.config中配置EffectsModule,但应用报错无法运行。
报错信息
TypeError: Cannot read properties of undefined (reading 'pipe') at effects.ts:14:19 at createEffect (ngrx-effects.mjs:85:47) at <instance_members_initializer> (effects.ts:13:21) at new _FeatureEffects (effects.ts:9:3) at Object.FeatureEffects_Factory [as factory] (effects.ts:31:6) at core.mjs:3132:35 at runInInjectorProfilerContext (core.mjs:866:5) at R3Injector.hydrate (core.mjs:3131:11) at R3Injector.get (core.mjs:3005:23) at injectInjectorOnly (core.mjs:1095:36)
Effects类代码
import { Injectable } from '@angular/core'; import { Actions, createEffect, ofType } from '@ngrx/effects'; import { of } from 'rxjs'; import { catchError, switchMap } from 'rxjs/operators'; import { addDocumentSuccess, loadDocumentsSuccess, loadDocumentsFailure } from './actions'; @Injectable() export class FeatureEffects { constructor(private actions$: Actions) { console.log(this.actions$); // Verify if `actions$` is initialized correctly } triggerAction2$ = createEffect(() => this.actions$.pipe( ofType(addDocumentSuccess), switchMap((action) => { const result = action.documents; // Ensure result is not undefined or null if (result) { return of(loadDocumentsSuccess({ documents: result })); } else { console.error('No documents found in action'); return of(loadDocumentsFailure({ error: 'No documents found' })); // Dispatch an error action if needed } }), catchError(error => { console.error('Error in effect:', error); return of(loadDocumentsFailure({ error: 'An error occurred' })); // Dispatch an error action }) ) ); }
app.config代码
import { ApplicationConfig, importProvidersFrom, provideZoneChangeDetection } from '@angular/core'; import { provideRouter } from '@angular/router'; import { provideAnimations } from '@angular/platform-browser/animations'; import { provideHttpClient, withInterceptors } from '@angular/common/http'; import { StoreDevtoolsModule } from '@ngrx/store-devtools'; import { StoreModule } from '@ngrx/store'; import { routes } from './app.routes'; import { addDocumentReducer, documentLoadReducer, documentProcessedReducer, LoginReducer } from './NgRx/reducer'; import { httpInterceptor } from './http.interceptor'; import { environment } from './environment'; import { EffectsModule } from '@ngrx/effects'; import { FeatureEffects } from './NgRx/effects'; export const appConfig: ApplicationConfig = { providers: [ provideZoneChangeDetection({ eventCoalescing: true }), provideRouter(routes), provideAnimations(), provideHttpClient(withInterceptors([httpInterceptor])), // Importing Store and Effects at the root level importProvidersFrom( StoreModule.forRoot({ loginState: LoginReducer, documentProcessedState: documentProcessedReducer, documentLoadingState: documentLoadReducer, addDocumentState: addDocumentReducer, }), // Add EffectsModule.forRoot() for initializing root effects EffectsModule.forRoot([FeatureEffects]), // Root effects can be provided here if any StoreDevtoolsModule.instrument({ maxAge: 25, // Retains last 25 states logOnly: environment.production, // Restrict extension to log-only mode }) // Add your feature effects here ) ] };
已尝试操作:同时使用EffectsModule.forRoot和.forFeature关联对应类,且将Effects配置置于StoreModule之后;调试确认Actions类型的actions$无法注入,排查无循环依赖,仍未找到原因。
解决方案
根据报错信息和代码分析,actions$未被正确注入导致调用pipe时抛出undefined错误,可从以下方向排查修复:
1. 确认NgRx依赖版本兼容性
- 检查
@ngrx/store、@ngrx/effects与Angular核心包的版本是否匹配,版本不兼容会导致依赖注入失效。执行以下命令查看版本:npm list @ngrx/store @ngrx/effects @angular/core - 若版本不匹配,升级或降级至官方兼容版本。
2. 修正Effects类的初始化逻辑
- 确保
Actions从@ngrx/effects正确导入,而非其他包。 - 显式添加return语句,确保逻辑在
actions$注入后执行(部分Angular版本下可规避时序问题):triggerAction2$ = createEffect(() => { return this.actions$.pipe( ofType(addDocumentSuccess), switchMap((action) => { const result = action.documents; if (result) { return of(loadDocumentsSuccess({ documents: result })); } else { console.error('No documents found in action'); return of(loadDocumentsFailure({ error: 'No documents found' })); } }), catchError(error => { console.error('Error in effect:', error); return of(loadDocumentsFailure({ error: 'An error occurred' })); }) ); });
3. 调整EffectsModule配置方式
- 若
FeatureEffects属于feature模块,应使用EffectsModule.forFeature([FeatureEffects])在对应feature模块中导入,而非根模块的forRoot。 - 确保
EffectsModule.forRoot在StoreModule.forRoot之后配置,模块顺序严格遵循Store优先、Effects次之的规则。
4. 启用严格模式排查注入问题
- 在
tsconfig.json中开启strictPropertyInitialization,强制检查类属性初始化:
该配置会帮助发现未正确初始化的依赖问题。{ "compilerOptions": { "strictPropertyInitialization": true } }
5. 清理缓存并重启服务
- 执行以下命令清理Angular和npm缓存:
ng cache clean npm cache clean --force - 重启开发服务器,避免缓存导致的依赖注入异常。
内容的提问来源于stack exchange,提问作者georgio bou sleimen
相关产品推荐
相关产品推荐

