Telling stories with code using pipe-able operators
Experimenting on telling the story of what exactly the code is meant to do using plain named functions and the .pipe()
operator of rxjs
Ever since I started using angular 2 and encountered the dot-chain style of operators in rxjs I wandered if there is a more readable and friendly way of doing the code. Consider the following code:
error$: Observable<Error>;const messages$ = error$
.filter(e => e != null)
.map(e => e.message || e.toString())
.scan((acc: string[], next: string) => acc.concat(next), [])
It is not very complex and yet the issue starts to emerge: one needs to read through all the code and understand what it does. But the author’s intent is not explicit. Now consider the following code:
error$: Observable<Error>;const messages$ = error$
.takeNonEmpty()
.extractMessage()
.accumulateInArray()
This is exactly what I would like to see. It is possible but far from straightforward. There is an example here (see Global augmentation near the end).
I think using the pipe method and pipe-able functions of rxjs we can do something very close to the above much easier.
In the error-console.component.ts I’ve created the functions with readable names that allow to be used in the pipe.
How do you write a pipe-able function? Easy — that’s a function that takes an observable and returns an observable. Easy — right? There is nothing stopping us to use some of the operators inside the telling-story named functions:
function skipInitial(errors$: Observable<any>): Observable<any> { return errors$.pipe( filter(x => x != "Init") );}
Now why would you want to do this and no simply leave the functions piped and be done with it? Readability and explicit intent are the main reasons. Try going reading someone else’s observable chain and guess what they meant to do. Event try going back to your own code with an observable chain. I’ve experienced difficulties in both these cases.
If I have the explicit intent of the author (even if it was me) I can easily read the code, spot an issue…
So what do you think? Like it? Too verbose? Code that’s hard-to-write should be hard-to-read?