简体   繁体   中英

Webservice call twice using dispatch and subscribe Angular 9

I don't understand why my create account api is twice called. When I delete the constructor part, the api is called one time but I need to get the success of my account creation.

I have a twice call webservice when i'm in the following configuration:

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,
      })
    );
  }

And in my constructor i'm looking for the success:

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 having following definition:

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 }>()
);

You. Should. Not. Subscribe. To. Effects.

Seriously.

If you need something done on USER_CREATE_SUCCESS you do it in the create$ effect, in another effect or in your reducers.


In your answer

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

should go into the effects (at least I would put it there if it is possible) to keep it clean. If not possible you're okay to leave it in the component.


The basic is that effects are automatically subscribed to (when registering them in the module) and should not subscribe to them anywhere else, since that causes your problem. As you already found out, you can use listen to the dispatched actions, since actions are the means of comunication for effects.

I have my answer (please be more tolerant about the Angular beginner than Kvetis):

I have to import action in my constructor and subscribe the success action:

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);
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM