I hope this fits more here than SO because it is mostly about code design than making it work. Also, this is not tied to RxJs, but more to the reactive paradigm. (TypeScript tag is only added to make the code highlighted.)
So this is what the code looks like, though this is just an overview. Actual function names are different than in the real world:
// Returns true if successfully tried to login
public tryLogin(userId: number): Observable<boolean> {
const result = new ReplaySubject<boolean>();
this.checkIfUserIsAuthorizedFromDatabase()
.subscribe(
user =>{
if(user.id === userId) {
result.next(true);
result.complete();
return;
}
this.checkIfUserHasAccess(user)
.subscribe(
access => {
if(access.banned) {
result.next(false);
result.complete();
return;
}
// ... many other nestings and function calls
// Watch the result passed in
this.checkLastWorkingLogin(user, result);
},
error => {
result.error(error)
// Sidenote: No idea why complete is called
result.complete()
}
)
},
error => result.error(error));
return result;
}
Problems with the current setup:
- a result object is passed around into functions, rather than the function to return a true/false
Observable
- the deeply nested code makes it hard to read
- since there is no single observable chain, the code is incredibly difficult to debug (can not use
tap
at a single place) Observable
s are used as an ES5Promise
, but they are much more than that
Observables would be needed to be connected somehow by flatMap
, but the chain should be finished up once the login process is terminally decided.
(Caching the single output is not a problem, observable will be simply cached.)
So can this code actually be refactored into something more readable that is more authentic to the libraries it is currently using?
Any suggestion is appreciated.