0

I have an angular dialog that uses ngrx to call an API.

The registerEvents is only about adding two subscriptions to an array, is only called in the constructor

But for some reason the code inside the fat-arrow of the two subscribes is getting called as soon as the dialog opens, I would expect only one "new data" message instead of two.

consoleMessages

Is almost like the registerEvents is executing the arrow functions or that the actions are being dispached automagically

constructor(@Inject(MAT_DIALOG_DATA) public data: any,
    private dialogRef: MatDialogRef<ScheduledAppointmentsDialogComponent>,
    private orderStore$: Store<OrdersState.State>)
{
    this.registerEvents();
}

registerEvents() {
    this.subscriptions.push(this.apptsForOrder$.subscribe((apptsForOrder: any[]) => {
      console.log("new data");
      this.apptsForOrder = apptsForOrder;
    }));

    this.subscriptions.push(this.updateAttachedAppointment$.subscribe((attachAppointment: boolean) => {
      console.log({ attachAppointment: attachAppointment });
      this.toogleLinkStatus();
    }, (err) => { console.log(err) }));

  }

ngOnInit(): void {
    // other code 
    this.loadApptsForOrder();
    // other code 
}

loadApptsForOrder() {
    this.orderStore$.dispatch(OrdersActions.loadApptsForOrder({ orderId: this.orderId }));
}

The loadApptsForOrder is only being called inside the onInit but there are two "new data" messages

I have tried changing from mergeMap to switchMap without any effect

attachAppointment$ = createEffect(() => this.actions$.pipe(
    ofType(actions.attachAppointment),
    mergeMap(args => this.orderService.attachAppointment(args.attachAppointmentRequest)
        .pipe(
            map(response => actions.attachAppointmentComplete({ attachAppointmentResponse: response.statusCode })),
            catchError(() => of(actions.attachAppointmentFailure({ error: 'fail' })))
        )
    )
));

Could this be an error with the way I have implemented the service/store ? in the way that I'm subscribing or what else ?

apptsForOrder$ and orderStore$ are observables<T>

  private apptsForOrder$ = this.orderStore$.select(OrdersSelectors.getApptsForOrder);
  private updateAttachedAppointment$ = this.orderStore$.select(OrdersSelectors.updateAttachedAppointment);
Mauricio Gracia Gutierrez
  • 10,288
  • 6
  • 68
  • 99
  • 1
    Is apptsForOrder$ a BehaviourSubject? See this "Upon subscription, it returns the last value of the subject. A regular observable only triggers when it receives an onnext" -> https://stackoverflow.com/questions/39494058/behaviorsubject-vs-observable – Conrado Lopez Aug 04 '21 at 14:15
  • 2
    That means, in Beahaviour Subjects , the callback is executed when subscribing and when the subject has a new value. In Subjects, the callback is executed only when the subject has a new value. – Conrado Lopez Aug 04 '21 at 14:17
  • @ConradoLopez - `apptsForOrder$` and `orderStore$` are `observables` - I have added their declarations – Mauricio Gracia Gutierrez Aug 04 '21 at 14:23

2 Answers2

1

Is apptsForOrder$ a BehaviourSubject? In Beahaviour Subjects the callback is executed when subscribing and when the subject has a new value. In Subjects, the callback is executed only when the subject has a new value.

See this: BehaviorSubject vs Observable?

Conrado Lopez
  • 131
  • 1
  • 6
1

NgRx selectors will start emitting values directly after subscription made. the first value emit is store current value. to disable this behavior on your component you can use RxJs operator skip(1) before subscribe.

Ayman Ali
  • 567
  • 4
  • 11