Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Can you give some non-trivial and not excessively contrived example of when observables should be used? I'm genuinely asking because, while I find them elegant, I still can't figure out why they were put front-and-center of the current generation of web frameworks (especially Angular). They seem a good tool to have but mostly for very particular cases.


I've had a lot of success using observables for side-effects in Redux and NGRX. It's flexible, testable, and reliable.

I can map, filter, etc. my app's actions to perform any side-effect I want, possibly sending a success or failure action on completion. I can even listen for changes in the store or other streams to dispatch actions.

You can still do everything you need with Thunk, Sagas, etc., but I enjoy the ease and flexibility that RxJS gives me.

Libraries that help with this pattern:

Redux Observables: https://redux-observable.js.org/

NGRX Effects: https://ngrx.io/guide/effects


This does a good job: https://gist.github.com/staltz/868e7e9bc2a7b8c1f754

We are using reactive programming basically everywhere. Example (Angular):

The Angular Router has an Observable "paramMap". We don't subscribe to it but are creating another Observable for the data that should be loaded.

  getData$ = (
    paramMap$: Observable<ParamMap>
  ): Observable<MyData> => {
    return paramMap$.pipe(
      // Create a query string
      map(paramMap => {
        // some pure function - business logic
        return getSomeQueryBasedOnTheRouteParams(
          paramMap 
        );
      }),
      // get the data
      // select$ is a method on the customStore that wraps the http client and does some more stuff
      // The switchMap is actually one of the concepts that I found initially not the easiest to understand 
      switchMap(someQuery=> {
        return this.customStore.select$({
          query: someQuery
        });
      }),
      map(rawData => {
        // pure function with business logic
        return modifyData(rawData);
      }),
      shareReplay()
    );
  };
Then it goes on with filtering, etc.

   getFilteredData$ = (
     // filter:$ is in our case a simple Subject we're calling next(newFilterValue)
     // NGRX, NGXS or Akita are popular state management libraries to manage this kind of state
     filter$: BehaviourSubject<string>,
     data$: Observable<MyData>): Observable<MyData> => {
        combineLatest(filter$, data$).pipe(
          // Do the filtering using pure functions
          map( ...
            return myFilterFuntion(filter, data);
          )
        )
   };
The filteredData$ Observable can be consumed via async pipe in a component.

The business logic is the same as in imperative-pull code. But using the abstraction of RxJS a lot of boilerplate and indirection vanishes. RxJS is not the easiest abstraction to learn (for me), but as with all, once you're comfortable a lot of the likely intimidating code above will become familiar. You just focus on writing business-logic in pure functions and combine it with RxJS.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: