Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Issue with Observable/Subject delay/throttle (ngIf & async)

I'm working with @ngrx/store and I'm displaying notification when request starts or returns an error and hiding it if request is successful. It works as intended, and I wanted to delay initial notification so it's not shown if request ends quickly. I've tried several Observable/Subject operators that work with time:

  • With delay and bufferTime message is null which causes an error in <notification>
  • Using debounceTime doesn't show initial message, but with slow responses and errors message is still null
  • throttleTime only shows initial notification and hides it with slow responses

Without any of these *ngIf="(notification |async)" does it's job and message is set only if notification isn't null.

I suppose I could just hide <notification> with CSS transition delay, but I was wondering if anyone knows other way to solve this...

@Component({
  template: `<notification [message]="notification |async" *ngIf="(notification |async)"></notification>`
})
export class RootRoute {
  constructor(...) {
    this.notification = this.store.select('notification')
      // None of these solve my issue:
      // .delay(250)
      // .throttleTime(250)
      // .debounceTime(250)
      // .bufferTime(250)
  }
}

export class Service {

  private request(method: any, values: any, endpointsUrl: string, actionType: string, storeSelector?) {
    this.store.dispatch({ type: "SHOW_NOTIFICATION", payload: {code: 200, message: "Getting data from server..."} });

    this._http.request(BASE_URL + endpointsUrl, { body: JSON.stringify(values), method: method })
      .map(response => response.json())
      .map(payload => ({ type: actionType, payload }))
      .subscribe({
        next: action => this.store.dispatch(action),
        error: payload => this.store.dispatch({ type: 'API_ERROR', payload }),
        complete: () => this.store.dispatch({ type: "HIDE_NOTIFICATION" })
      });

    if (storeSelector)
      return this.store.select(storeSelector);
  }

}
like image 384
Sasxa Avatar asked Dec 28 '25 16:12

Sasxa


1 Answers

I ended up with:

this.store.select('notification')
  .debounceTime(250)
  .subscribe((message: INotification) => this.notification = message);

and reverted back to ChangeDetectionStrategy.Default for this component. I guess it's one of the issues with async pipe...

like image 188
Sasxa Avatar answered Dec 30 '25 21:12

Sasxa