Manuel Brás
Manuel Brás

Reputation: 513

Condense observable operations into single chain

I have a segment of code containing some observable operations which I think should be possible to condense as they share the same end goal. However as I am fairly new to RxJs I can't quite figure out how to do it. Any suggestions? Thanks.

    if (isCommerceOrV3) {
                linkObservable$ = this.handleCommerceOrV3Notifications(parsedUrl).pipe(
                        switchMap(isExternalOrGoToSection => {
                            if (isExternalOrGoToSection) {
                                return this.linksManager.handleLink(url, sectionId);
                            }

                            return EMPTY;
                        }
                    ));
                } else {
                    linkObservable$ = this.handleClassicNotifications(parsedUrl).pipe(
                        switchMap(isExternalOrGoToSection => {
                            if (isExternalOrGoToSection) {
                                return this.linksManager.handleLink(url, sectionId);
                            }

                            return EMPTY;
                        }
                    ));
                }
    }

Upvotes: 0

Views: 57

Answers (3)

Barremian
Barremian

Reputation: 31125

How about iif for outer condition and ternary operator for inner observable?

Try the following

linkObservable$ = iif(
  () => isCommerceOrV3,
  this.handleCommerceOrV3Notifications(parsedUrl),
  this.handleClassicNotifications(parsedUrl)
).pipe(
  switchMap((isExternalOrGoToSection: any) => 
    isExternalOrGoToSection
      ? this.linksManager.handleLink(url, sectionId)
      : EMPTY
  )
);

Upvotes: 2

Theunis
Theunis

Reputation: 466

There really is quite a few ways to do this. The following answer is the same as Alexey's, just with some more detail. To me this also seems to be the most elegant solution:

const notificationOperation = isCommerceOrV3
  ? this.handleCommerceOrV3Notifications
  : this.handleClassicNotifications;

linkObservable$ = notificationOperation(parsedUrl).pipe(
  switchMap(isExternalOrGoToSection => isExternalOrGoToSection
    ? this.linksManager.handleLink(url, sectionId)
    : EMPTY;
  )
);

If it's not clear, in the top part we reference the relevant method to a function variable using a ternary operator on the isCommerceOrV3 boolean(?).

In the next part we invoke the respective method via the notificationOperation reference variable and use the common piping sequence.

In the switchMap we also use the arrow function shorthand without a code block, returning another ternary statement and the relevant observable.

Upvotes: 1

Alexey Romanov
Alexey Romanov

Reputation: 170859

linkObservable$ = (isCommerceOrV3 ? this.handleCommerceOrV3Notifications(parsedUrl) : this.handleClassicNotifications(parsedUrl)).pipe(...)

though it's likely more readable if you extract the ternary into a variable:

const someNameThatMakesSenseInContext = isCommerceOrV3 ? this.handleCommerceOrV3Notifications(parsedUrl) : this.handleClassicNotifications(parsedUrl)
linkObservable$ = someNameThatMakesSenseInContext.pipe(...)

Upvotes: 1

Related Questions