You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

已引入必要模块且无循环依赖,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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 16:48:14