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:
// Observable returns true, if the action has been successfully executed
const tryLogin = (id: number): Observable<boolean> => {
const result = new ReplaySubject<boolean>();
// Operation 1
loadUserFromDB(id)
.subscribe(
user => {
// Early stop 1 - true
if (user.name === 'Sarah' || user.id === 0) {
result.next(true);
result.complete();
return;
}
// Operation 2, dependent on Operation 1
checkMasterData(user)
.subscribe(
loginInformation => {
const {userId, lastLogin} = loginInformation;
// Early stop 2 - false
if (lastLogin === 'LAST_YEAR') {
result.next(false);
result.complete();
return;
}
// Operation 3, dependent on Operation 1 and Operation 2 's success
createNewUserId({attemptedUserId: userId})
.subscribe(
// Operation N...
// createAccountFromLogin function also has a similar structure to `tryLogin`
newId => createAccountFromLogin(newId, result),
error => result.error(error)
);
},
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.