2

I have some common code which needs to be executed as a callback in either of (if/else) aysnc function call. Following is the hypothetical snippet of my code.

if(condition1) {
    asyncFun1().subscribe((result) => {
        commonCode
    })
} else {
    asyncFun2().subscribe((result) => {
        commongcode
    })
}

You can see that commonCode is needed to be written in two places. I cannot put it after if/else as it depend on result. How can I remove this anti-pattern?

2
  • 2
    (condition1 ? asyncFun1 : asyncFun2)().subscribe(...)? Commented Jul 5 at 9:42
  • Related: if-else flow in promises Commented Jul 5 at 21:39

4 Answers 4

2

An arrow function is an object just like almost anything else in JS. You don't have to pass them inline, but can store them in a variable and pass that to your function instead.

From the initial code using inline functions:

if(condition1) {
    asyncFun1().subscribe((result) => {
        commonCode
    })
} else {
    asyncFun2().subscribe((result) => {
        commongcode
    })
}

you can extract them to variables:

if(condition1) {
    const callback = (result) => {
        commonCode
    };
    asyncFun1().subscribe(callback);
} else {
    const callback = (result) => {
        commonCode
    };
    asyncFun2().subscribe(callback);
}

And in the next step, move the shared statements out of the conditional:

const callback = (result) => {
    commonCode
};
if(condition1) {
    asyncFun1().subscribe(callback);
} else {
    asyncFun2().subscribe(callback);
}

Next, you see that calling subscribe is shared as well, the only difference is the object it is being called on. You might want to move that out of the condition as well (or you might want to keep it, it really depends)

const callback = (result) => {
    commonCode
};
const subscribable;
if(condition1) {
    subscribable = asyncFun1();
} else {
    subscribable = asyncFun2();
}
subscribable.subscribe(callback);

or

const callback = (result) => {
    commonCode
};
const subscribable = condition1
    ? asyncFun1()
    : asyncFun2();
subscribable.subscribe(callback);

and then you might just inline everything again, arriving at:

(condition1 ? asyncFun1() : asyncFun2()).subscribe((result) => {
    commonCode
});

Keep the variables if they make your code easier to understand (e.g. keeping subscribable, but inlining callback could make it clearer)

Sign up to request clarification or add additional context in comments.

Comments

0

I have converted observable to promise and then use await. Don't know this would be right approach or not. There must be better solution.

let result;

if(condition1) {
    result = await firstValueFrom(asyncFun1())
           
} else {
    result = await firstValueFrom(asyncFun2())
}

commongcode

1 Comment

Even then, you should rather write const result = await firstValueFrom(condition1 ? asyncFunc1() : asyncFunc2());. But unless you want to use async/await with promises instead of rxjs operators with observables, why don't you go with @knittl's answer?
0

Since you want to subscribe to a different observable depending on a condition and execute the same logic on the emitted result, declare your observable based on the condition like this (very similar to @knittl's answer part 5):

const observable$ = condition1 ? asyncFun1() : asyncFun2();

Then simply subscribe to it:

observable$.subscribe(result => /* common code */ );

Comments

-2

You extract the entire callback and store it in a constant. Then you pass that same constant to the call to subscribe

Comments

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.