3

I'm in the midst of refactoring some old rxjs code which was written poorly and therefore has some race conditions.

So I'd like to use a chain of filter() operators based on various conditions; however I need it to visit EVERY filter operator along this chain. i.e. If Condition1 is true, execute the next switchMap() - otherwise just follow down to the next filter(). Apply the same logic to Condition2..Condition4.

Also, my selectedNode needs to be emitted down the chain because the getChildNodes() function fetches additional child nodes and pushes them onto selectedNode.

Right now it just bails on when it encounters the first FALSY condition - so naturally the rest of the filters will never get checked.

How do I make it such that if will execute as an old IF...THEN statement on each condition?

Here's what I have so far:

    constructor(private readonly configSvc: ConfigService) {
        this.model$
            .pipe(
                filter((selectedNode) => !!selectedNode),

                // if condition1 passes, get child nodes of current node.
                filter((selectedNode) => myCondition1),
                switchMap((selNode) => this.getChildNodes(selNode, NodeType.Type1)),

                // if condition2 passes..
                filter((selectedNode) => myCondition2),
                switchMap((selNode) => this.getChildNodes(selNode, NodeType.Type2)),

                // if condition3 passes..
                filter((selectedNode) => myCondition3),
                switchMap((selNode) => this.getChildNodes(selNode, NodeType.Type3)),

                // if condition4 passes, get child nodes...
                filter((selectedNode) => myCondition4),
                switchMap((selNode) => this.getChildNodes(selNode, NodeType.Type4)),

                takeUntil(this.onDestroy),
            )
            .subscribe({
                next: (selectedNode: SelectedNode) => { // init the Network tree and notify listeners
                    this.initNetwork(selectedNode);
                    this.configNodesReadySource.next(selectedNode);
                },
            });
    }

or perhaps subscribing to mult observables, an an alt idea:

const condition1$ = this.model$.pipe(filter((node) => condition1), switchMap(...);
const condition2$ = this.model$.pipe(filter(...), switchMap(...);
const condition3$ = this.model$.pipe(filter(...), switchMap(...);
const condition4$ = this.model$.pipe(filter(...), switchMap(...);

forkJoin(...).subsribe(...); // join condition1 thru 4 to get final result ???

However, it seems I have the same problem or similar. I NEVER reach the subscribe.

2
  • 1
    Not sure which version of RxJS you're using, but I believe iif could do the trick. Commented Dec 14, 2021 at 14:39
  • 6.6.3 and angular 13 Commented Dec 14, 2021 at 17:53

1 Answer 1

4

You can use concatMap to achieve cascading as described

this.model$
.pipe(
    filter((selectedNode) => !!selectedNode),
    concatMap(selectedNode => myCondition1 ? this.getChildNodes(selectedNode, NodeType.Type1) : of(selectedNode)),
    concatMap(selectedNode => myCondition2 ? this.getChildNodes(selectedNode, NodeType.Type2) : of(selectedNode)),
    concatMap(selectedNode => myCondition3 ? this.getChildNodes(selectedNode, NodeType.Type3) : of(selectedNode)),
    concatMap(selectedNode => myCondition4 ? this.getChildNodes(selectedNode, NodeType.Type4) : of(selectedNode)),
    takeUntil(this.onDestroy),
)
.subscribe({
    next: (selectedNode: SelectedNode) => { // init the Network tree and notify listeners
        this.initNetwork(selectedNode);
        this.configNodesReadySource.next(selectedNode);
    },
});
Sign up to request clarification or add additional context in comments.

4 Comments

but my selectedNode needs to be emitted down the chain because the getChildNodes() function fetches additional child nodes and pushes them onto selectedNode, then returns an Observable.
@bob.mazzo Please check my new edit
Good idea, and this might work for me. However I would need of(selectedNode) in order to emit that as an Observable to the next operator in the chain.
Yep, that was definitely a mistake in my answer, should have had of(selectedNode) instead

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.