samedi 2 septembre 2023

Facade Pattern for rxjs streams for cleaner Angular architecture?

For context:

I'm working on an Angular 15 app, where I distinguish between smart and dumb components. My smart components do have connection to services, whereas the dumb components only communicate via Inputs and Outputs with the smart component and do not get any services injected.

Within the smart components I use a reactive declarative (rxjs) approach to react to events. However, by now these smart components involve many reactive streams which makes the component bloated.

As these smart components are kind of "collectors" of many events and the "access" to the api service, I don't see reasonable way how I could break up the component into smaller parts.

Question:

I was thinking about using Design Patterns, e.g. the Facade Pattern, to declutter the component by putting the reactive streams into a separate service and the component would only have to subscribe to the final observables and handle the side effects (like UI updates).

However, I wonder if this would be a smart approach and if there are better ways to deal with this situation.

Example of complex smart component:

class MySmartComponent {
  // ... several @Input and private members

  // Multiple RxJS streams to handle different scenarios
  dataFromRoute$: Data[] = this.route.url.pipe(/* ... */);
  dataAfterAdded$: Data[] = this.addDataButtonClick$.pipe(/* ... */);
  dataAfterMore$: Data[] = this.getMoreDataButtonClick$.pipe(/*...*/);
  dataAfterDeleted$: Data[] = this.deleteDataButtonClick$.pipe(/* ... */);

  data$: Observable<Data[]> = merge(
        this.dataFromRoute$,
        this.dataAfterAdded$,
        this.dataAfterMore$
        this.dataAfterDeleted$,
    ).pipe(/*...*/);

  searchInput$ = new BehaviorSubject<string>(''); // user can search/filter Data

  // subscription only to this Observable via async pipe in template!
  filteredData$: Observable<Data[] | null> = combineLatest([
        this.data$,
        this.dataSearchInput$,
    ]).pipe(

  // function calls by child components
  onSearchInputChange(value: string) { /* ... */ }
  onDeleteDataClick(event: SomeEvent) { /* ... */ }
  // ... more logic
}

Aucun commentaire:

Enregistrer un commentaire