design – How to (or should I) refactor RxJS nested subscriptions with intermediate return value?

Yes, you should definitely refactor this code to use regular return values. The use of Rx simply doesn’t make any sense in this context.

Assuming the whole application is developed in this style, you have quite a task before you. You certainly want to do this one step at a time and make sure you always have a working application.

There are several ways by which you could approach this. The safest, though not necessarily quickest way I can see is the following:

  • Each function gets a wrapper function that does nothing but reduce the Observable<T> returned by the original function into the actual T return value you want to have.

    So you’ll have a reducedTryLogin, reducedCheckIfUserIsAuthorizedFromDatabase, etc.

  • You replace the implementation of the reducedXXX functions. Instead of simply reducing the result of XXX, you’ll use the other wrapper functions to implement the actual functionality.

Let’s take tryLogin as an example. Originally, your reducedTryLogin function will simply be something like

public reducedTryLogin(userId: number): boolean {
    return tryLogin(number).reduce((acc, val) => acc || val, false);

But once you have reducedTryCheckIfUserIsAuthorizedFromDatabase and reducedCheckIfUserHasAccess, etc. you can replace it with

public reducedTryLogin(userId: number): boolean {
    var user = reducedTryCheckIfUserIsAuthorizedFromDatabase();
    if (user.Id === userId)
        return true;

    var access = reducedCheckIfUserHasAccess();
    if (access.banned)
        return false;

    // etc.

At this point, you can flip things around and make the original tryLogin function simply call reducedTryLogin and push the result through a Subject. Finally, you can remove it altogether when you’ve updated all callers.

Observables can make the code much clearer when you actually want to apply an operation to a stream of things. Outside of that, they just obscure the code and I expect the readability of your code to improve significantly once you’ve removed the use of Rx where it isn’t appropriate.