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

Angular添加provideEffects触发Object.defineProperty错误,移除后Effects失效

问题描述

在Angular项目中配置provideEffects(AuthEffects)时触发Object.defineProperty called on non-object错误,错误栈如下:

at Function.defineProperty (<anonymous>)
    at Module.createEffect (/Users/stefanoantonetti/WebstormProjects/ngrx-counter-a17/.angular/cache/18.2.4/vite/deps_ssr/@ngrx_effects.js:50:10)
    at _AuthEffects.<instance_members_initializer> (/Users/stefanoantonetti/WebstormProjects/ngrx-counter-a17/src/app/auth/state/auth.effects.ts:13:12)
    at new _AuthEffects (/Users/stefanoantonetti/WebstormProjects/ngrx-counter-a17/src/app/auth/state/auth.effects.ts:30:3)
    at map (/Users/stefanoantonetti/WebstormProjects/ngrx-counter-a17/src/app/auth/state/auth.effects.ts:30:101)
    at eval (/Users/stefanoantonetti/WebstormProjects/ngrx-counter-a17/.angular/cache/18.2.4/vite/deps_ssr/chunk-S4UJ36BC.js:4456:35)
    at runInInjectorProfilerContext (/Users/stefanoantonetti/WebstormProjects/ngrx-counter-a17/.angular/cache/18.2.4/vite/deps_ssr/chunk-S4UJ36BC.js:3058:5)
    at R3Injector.hydrate (/Users/stefanoantonetti/WebstormProjects/ngrx-counter-a17/.angular/cache/18.2.4/vite/deps_ssr/chunk-S4UJ36BC.js:4455:11)
    at R3Injector.get (/Users/stefanoantonetti/WebstormProjects/ngrx-counter-a17/.angular/cache/18.2.4/vite/deps_ssr/chunk-S4UJ36BC.js:4345:23)
    at injectInjectorOnly (/Users/stefanoantonetti/WebstormProjects/ngrx-counter-a17/.angular/cache/18.2.4/vite/deps_ssr/chunk-S4UJ36BC.js:3190:36

移除该配置后,auth.effects.ts中的登录Effect无法发起API请求。


相关代码

AuthEffects类

import {Injectable} from "@angular/core";
import {Actions, createEffect, ofType} from "@ngrx/effects";
import {AuthService} from "../services/auth.service";
import {Router} from "@angular/router";
import {loginFailure, loginStart, loginSuccess} from "./auth.actions";
import {catchError, exhaustMap, map, of, tap} from "rxjs";
import {AuthResponse} from "../../models/auth-response.model";


@Injectable()
export class AuthEffects {

  login$ = createEffect(() => {
    return this.actions$?.pipe(
      ofType(loginStart),
      tap(action => console.log('Effetto login innescato', action)),
      exhaustMap((action) =>
        this.authService.login(action.email, action.password).pipe(
          map((authResponse: AuthResponse) => {
            console.log(authResponse)
            this.router.navigate(['home']).then()
            return loginSuccess()
          }),
          catchError(() => of(loginFailure()))
        )
      )
    );
  });

  constructor(private actions$: Actions, private authService: AuthService, private router: Router) {}
}

app.config.ts配置

import {ApplicationConfig, isDevMode, provideZoneChangeDetection} from "@angular/core";
import {provideRouter} from "@angular/router";
import {routes} from "./app.routes";
import {provideClientHydration} from "@angular/platform-browser";
import {provideHttpClient, withFetch} from "@angular/common/http";
import {provideStore} from "@ngrx/store";
import {counterReducer} from "./counter/state/counter.reducer";
import {postsReducer} from "./posts/state/posts.reducer";
import {authReducer} from "./auth/state/auth.reducer";
import {provideEffects} from "@ngrx/effects";
import {AuthEffects} from "./auth/state/auth.effects";
import {provideStoreDevtools} from "@ngrx/store-devtools";


export const appConfig: ApplicationConfig = {
  providers: [
    provideZoneChangeDetection({ eventCoalescing: true }),
    provideRouter(routes), provideClientHydration(),
    provideHttpClient(withFetch()),
    provideStore({
      counter: counterReducer,
      posts: postsReducer,
      auth: authReducer,
    }),
    provideEffects(AuthEffects),
    provideStoreDevtools({ maxAge: 25, logOnly: !isDevMode() })
]
};

解决方法

错误核心原因是Effect初始化时返回了undefined:你在createEffect的工厂函数中使用了可选链this.actions$?.pipe(),当this.actions$还未完成注入时,可选链会返回undefined,而NgRx Effects要求createEffect必须返回有效的Observable流。

修复步骤

  1. 移除可选链操作符:将this.actions$?.pipe()改为this.actions$.pipe()。Angular的依赖注入会确保Actions服务在Effect实例化时已完成注入,无需担心this.actions$为null/undefined。
  2. 保持返回Observable流:确保createEffect的工厂函数始终返回一个Observable,而非undefined。

修改后的login$ Effect代码:

login$ = createEffect(() => {
  return this.actions$.pipe(
    ofType(loginStart),
    tap(action => console.log('Effetto login innescato', action)),
    exhaustMap((action) =>
      this.authService.login(action.email, action.password).pipe(
        map((authResponse: AuthResponse) => {
          console.log(authResponse)
          return loginSuccess()
        }),
        tap(() => this.router.navigate(['home'])),
        catchError(() => of(loginFailure()))
      )
    )
  );
});

额外优化建议

将router.navigate移到tap操作符中,避免在map里处理副作用,符合NgRx“纯转换+副作用分离”的最佳实践。


内容的提问来源于stack exchange,提问作者Stefano Antonetti

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 06:05:56