Skip to main content
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Tweeted twitter.com/StackSoftEng/status/1178912528384049153
Bumped by Community user
Bumped by Community user
Refactored example
Source Link
andras
  • 212
  • 1
  • 6
// ReturnsObservable returns true, if successfullythe triedaction tohas loginbeen successfully executed
publicconst tryLogin = (userIdid: number): Observable<boolean> => {
    const result = new ReplaySubject<boolean>();

    this.checkIfUserIsAuthorizedFromDatabase// Operation 1
    loadUserFromDB(id)
        .subscribe(
            user => {
                // Early stop 1 - true
                if (user.name === 'Sarah' || user.id === userId0) {
                    result.next(true);
                    result.complete();
                    return;
                } 

                // Operation 2, dependent on Operation 1
                this.checkIfUserHasAccesscheckMasterData(user)
                    .subscribe(
                        accessloginInformation => {
                            const {userId, lastLogin} = loginInformation;

                            // Early stop 2 - false
                            if (access.bannedlastLogin === 'LAST_YEAR') {
                                result.next(false);
                                result.complete();
                                return;
                            } 

                            // ...Operation many3, otherdependent nestingson Operation 1 and functionOperation calls2 's success
                            createNewUserId({attemptedUserId: userId})
                                .subscribe(
                                    // WatchOperation theN...
 result passed in                                 // createAccountFromLogin function also has a similar structure to `tryLogin`
                            this.checkLastWorkingLogin        newId => createAccountFromLogin(usernewId, result),
                                    error => result.error(error)
                                );
                        },
                        error => {
                            result.error(error);

                            // Sidenote: No idea why complete is called
                            result.complete()   ;
                        }
                    );
            },
            error => result.error(error)
        );

    return result;
};

Any suggestion is appreciated.

Full code that also includes function declarations.

// 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;
}

Any suggestion is appreciated.

// 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;
};

Any suggestion is appreciated.

Full code that also includes function declarations.

Added input parameter to make it clear
Source Link
andras
  • 212
  • 1
  • 6
// 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;
}
// 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()
                    .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;
}
// 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;
}
Added reason why code is bad
Source Link
andras
  • 212
  • 1
  • 6
  • 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)
  • Observables are used as an ES5 Promise, but they are much more than that
  • 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)
  • 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)
  • Observables are used as an ES5 Promise, but they are much more than that
Source Link
andras
  • 212
  • 1
  • 6
Loading