0
votes

I've been using Angular for a while. And recently, I'm keeping thinking(and searching) what's the preferred practice to subscribe an Observable like Subject, which will get emitted by a certain DOM event.

For example (Which I think may be a neat and clean implementation here?)

<!-- component.html -->
<div>
  <button (click)="clickEvent$.next($event)">Click Me!</button>
</div>
// component.ts

...
class Component implements OnInit, OnDestroy {
  public clickEvent$ = new Subject();

  private subscriptions = new Subscription();

  public ngOnInit() {
    this.subscriptions.add(this.handleClick(this.clickEvent$));
  }

  public ngOnDestroy() {
    this.subscriptions.unsubscribe();
  }

  public handleClick<T>(subject: Subject<T>): Subscription {
    return subject.pipe(debounceTime(300)).subscribe(
      event => {
        // do something
      }
    );
  }

}
...

So I wonder if there is any better or recommended implementation. If so please do share it :)

1
Is there a specific purpose you trying to achieve by doing this? - Rafi Henig
@RafiHenig Just to keep code clean and easy to understand. Though it's not a common condition, but as the number of subjects increasing, the code of subscribing part could be heavy... - frodoluo

1 Answers

1
votes
<!-- component.html -->
<div>
 <button (click)="clickEvent($event)">Click Me!</button>
</div>

//service.ts
@Injectable()
export class Service {
  private missionAnnouncedSource: Subject<string> = new Subject<string>();
  public readonly subjToObservable$ = this.missionAnnouncedSource.asObservable();
  
  constructor() { }

  public setMisson(misson: string): void {
     this.missionAnnouncedSource.next(mission)
  }
}

// component.ts
class Component implements OnInit, OnDestroy {
   private destroySubject$: Subject<void> = new Subject();
   public mission: string

   constructor(service: Service) {
   }

   ngOnInit() {
     this.service.subjToObservable$
       .pipe(
         takeUntill(this.destroySubject$)
       )
       .subscribe((mission) => {
         this.mission = mission
       })
   }

   public clickEvent($event):void {
      this.service.setMission('mission');
   }

   ngOnDestroy() {
     this.destroySubject$.next();
     this.destroySubject$.complete();
   }    
}

this is a possible way to communicate with subjects via dom events angular doc