使用分派和订阅调用 Web 服务两次 Angular 9

Webservice call twice using dispatch and subscribe Angular 9

我不明白为什么我的创建帐户 api 被调用了两次。当我删除构造函数部分时,api 被调用一次,但我需要成功创建帐户。

当我处于以下配置时,我有两次调用 webservice :

public onSubmit() {
    this.submitted = true;
    // stop here if form is invalid
    if (this.registerForm.invalid) {
      return;
    }
    this.store.dispatch(
      userAction.userCreateRequest({
        data: this.registerForm.value,
      })
    );
  }

在我的 constructor 中,我正在寻找成功 :

constructor(
    private store: Store<fromRoot.State>,
    private formBuilder: FormBuilder,
    private route: ActivatedRoute,
    private userEffects: UserEffects,
    private modalService: NgbModal,
    private sanitizer: DomSanitizer,
    private userService: UserService ) {
  this.loading$ = store.select(fromRoot.getUserLoading);
  this.userEffects.create$
  .pipe(ofType(UserTypes.USER_CREATE_SUCCESS))
  .subscribe((res) => {
    console.log("SUCCESSS TEST");
  });
}

effect.ts 具有以下定义:

create$ = createEffect(() =>
  this.actions$.pipe(
    ofType(UserTypes.USER_CREATE_REQUEST),
    exhaustMap((action) => {
      const { data } = action;
      return this.userService.create(data as UserActions.UserInfosData).pipe(
        map((user) => UserActions.userCreateSuccess({ user })),
        catchError((error) =>
          of(UserActions.userCreateFailure({ error }))
        )
      );
    })
  )
);

action.ts :

// create User
export const userCreateRequest = createAction(
  UserTypes.USER_CREATE_REQUEST,
  props<{ data: UserInfosData }>()
);
export const userCreateSuccess = createAction(
  UserTypes.USER_CREATE_SUCCESS,
  props<{ user: any }>()
);
export const userCreateFailure = createAction(
  UserTypes.USER_CREATE_FAILURE,
  props<{ error: any }>()
);

你。应该。不是。订阅。到。效果。

说真的。

如果您需要在 USER_CREATE_SUCCESS 上完成某些事情,您可以在 create$ 效果、另一个效果或您的减速器中完成。


在你的回答中

this.actions$.pipe(ofType(UserTypes.USER_CREATE_SUCCESS))
  .subscribe((res) => {
    console.log("SUCCESSS");
    // this.open(this.alertModal, 'modal-custom alert-modal');
  });

应该进入效果(如果可能的话至少我会把它放在那里)以保持它的清洁。如果不可能,您可以将其留在组件中。


基本原理是自动订阅效果(当在模块中注册它们时)并且不应在其他任何地方订阅它们,因为这会导致您的问题。正如您已经发现的那样,您可以使用监听调度的动作,因为动作是效果通信的方式。

我有我的答案(请对 Angular 初学者比 Kvetis 更宽容):

我必须在构造函数中导入操作并订阅成功操作:

constructor(
    private store: Store<fromRoot.State>,
    private formBuilder: FormBuilder,
    private route: ActivatedRoute,
    private modalService: NgbModal,
    private userService: UserService,
    private actions$: Actions,
  ) {
    this.loading$ = store.select(fromRoot.getUserLoading);
    this.specificDiets$ = store.select(fromRoot.getAppSpecificDiets);
    // this.foods$ = store.select(fromRoot.getAppFoods);
    this.foodGroups$ = store.select(fromRoot.getAppFoodGroups);
    this.physicalActivities$ = store.select(fromRoot.getAppPhysicalActivities);
    this.foodHabits$ = store.select(fromRoot.getAppFoodHabits);
    this.actions$.pipe(ofType(UserTypes.USER_CREATE_SUCCESS))
      .subscribe((res) => {
        console.log("SUCCESSS");
        // this.open(this.alertModal, 'modal-custom alert-modal');
      });
    this.vitrineProducts$ = store.select(fromRoot.getAppVitrineProducts);
  }