rxjs conditional nesting observables
up vote
1
down vote
favorite
I have the following code which is working as intended:
const sourceObservable = ... // irrelevant
sourceObservable.subscribe(x => {
doAnyway(x);
if (x.Id) {
doSometing(x);
} else {
// id Not set, get default Id
this.idService.getDefault().subscribe(id => {
x.Id = id;
doSometing(x);
});
}
});
According to this article nested subscribes are to avoid. Thats why i tried to refactor the above code, using pipes. I tried to realize the if-else operation with this Method, where filtering is used to create an observable branch for each option. And in the end they should be merged to subscribe.
const obsShared = sourceObservable.pipe(
tap(x => {
doAnyway(x);
}),
share());
const obsIdNotSet = obsShared.pipe(
filter(x => !x.kennzahlId),
merge(x => idService.getDefault().subscribe(id => {
x.Id = id;
// doSomething(x) will nomore be executed here
})));
// even though the true-part is empty I seem to need this to mergeing both options
const obsIdSet = obsShared.pipe(
filter(x => !!x.Id),
tap(() => {
// doSomething(x) will nomore be executed here
}));
obsIdSet.pipe(merge(obsIdNotSet)).subscribe(x => {
// in case obsIdNotSet this will run with x.Id not set because x.Id will be set later
doSometing(x);
});
This code does compile and run without errors, only does it execute doSomething(x)
before calling idService.getDefault().....
and though it will be called without x.Id being set.
What am i doing wrong?
angular typescript rxjs
add a comment |
up vote
1
down vote
favorite
I have the following code which is working as intended:
const sourceObservable = ... // irrelevant
sourceObservable.subscribe(x => {
doAnyway(x);
if (x.Id) {
doSometing(x);
} else {
// id Not set, get default Id
this.idService.getDefault().subscribe(id => {
x.Id = id;
doSometing(x);
});
}
});
According to this article nested subscribes are to avoid. Thats why i tried to refactor the above code, using pipes. I tried to realize the if-else operation with this Method, where filtering is used to create an observable branch for each option. And in the end they should be merged to subscribe.
const obsShared = sourceObservable.pipe(
tap(x => {
doAnyway(x);
}),
share());
const obsIdNotSet = obsShared.pipe(
filter(x => !x.kennzahlId),
merge(x => idService.getDefault().subscribe(id => {
x.Id = id;
// doSomething(x) will nomore be executed here
})));
// even though the true-part is empty I seem to need this to mergeing both options
const obsIdSet = obsShared.pipe(
filter(x => !!x.Id),
tap(() => {
// doSomething(x) will nomore be executed here
}));
obsIdSet.pipe(merge(obsIdNotSet)).subscribe(x => {
// in case obsIdNotSet this will run with x.Id not set because x.Id will be set later
doSometing(x);
});
This code does compile and run without errors, only does it execute doSomething(x)
before calling idService.getDefault().....
and though it will be called without x.Id being set.
What am i doing wrong?
angular typescript rxjs
add a comment |
up vote
1
down vote
favorite
up vote
1
down vote
favorite
I have the following code which is working as intended:
const sourceObservable = ... // irrelevant
sourceObservable.subscribe(x => {
doAnyway(x);
if (x.Id) {
doSometing(x);
} else {
// id Not set, get default Id
this.idService.getDefault().subscribe(id => {
x.Id = id;
doSometing(x);
});
}
});
According to this article nested subscribes are to avoid. Thats why i tried to refactor the above code, using pipes. I tried to realize the if-else operation with this Method, where filtering is used to create an observable branch for each option. And in the end they should be merged to subscribe.
const obsShared = sourceObservable.pipe(
tap(x => {
doAnyway(x);
}),
share());
const obsIdNotSet = obsShared.pipe(
filter(x => !x.kennzahlId),
merge(x => idService.getDefault().subscribe(id => {
x.Id = id;
// doSomething(x) will nomore be executed here
})));
// even though the true-part is empty I seem to need this to mergeing both options
const obsIdSet = obsShared.pipe(
filter(x => !!x.Id),
tap(() => {
// doSomething(x) will nomore be executed here
}));
obsIdSet.pipe(merge(obsIdNotSet)).subscribe(x => {
// in case obsIdNotSet this will run with x.Id not set because x.Id will be set later
doSometing(x);
});
This code does compile and run without errors, only does it execute doSomething(x)
before calling idService.getDefault().....
and though it will be called without x.Id being set.
What am i doing wrong?
angular typescript rxjs
I have the following code which is working as intended:
const sourceObservable = ... // irrelevant
sourceObservable.subscribe(x => {
doAnyway(x);
if (x.Id) {
doSometing(x);
} else {
// id Not set, get default Id
this.idService.getDefault().subscribe(id => {
x.Id = id;
doSometing(x);
});
}
});
According to this article nested subscribes are to avoid. Thats why i tried to refactor the above code, using pipes. I tried to realize the if-else operation with this Method, where filtering is used to create an observable branch for each option. And in the end they should be merged to subscribe.
const obsShared = sourceObservable.pipe(
tap(x => {
doAnyway(x);
}),
share());
const obsIdNotSet = obsShared.pipe(
filter(x => !x.kennzahlId),
merge(x => idService.getDefault().subscribe(id => {
x.Id = id;
// doSomething(x) will nomore be executed here
})));
// even though the true-part is empty I seem to need this to mergeing both options
const obsIdSet = obsShared.pipe(
filter(x => !!x.Id),
tap(() => {
// doSomething(x) will nomore be executed here
}));
obsIdSet.pipe(merge(obsIdNotSet)).subscribe(x => {
// in case obsIdNotSet this will run with x.Id not set because x.Id will be set later
doSometing(x);
});
This code does compile and run without errors, only does it execute doSomething(x)
before calling idService.getDefault().....
and though it will be called without x.Id being set.
What am i doing wrong?
angular typescript rxjs
angular typescript rxjs
edited yesterday
trichetriche
23.5k41949
23.5k41949
asked yesterday
LuckyLikey
1,1851029
1,1851029
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
up vote
4
down vote
accepted
the following is the cleanest way to handle that (according to me) :
source.pipe(
tap(val => doAnyway(val)),
switchMap(val => val.id ? of(val.id) : this.idService.getDefault())
).subscribe(id => {
this.id = id;
doSomething(id);
});
You can see how short and clear this is, and it does the exact same thing your first code was doing.
could I also provide a mapping function to map the result ofthis.idService.getDefault()
if the result wasn't an Id itself?
– LuckyLikey
yesterday
Sure,this.idService.getDefault().pipe(map(...))
(you can use pipes within pipes, there's no issue with that)
– trichetriche
yesterday
you must truly be my captain :) Addedimport 'rxjs/add/observable/of';
but it doesn't seem to be found. Im using angular 6
– LuckyLikey
yesterday
@LuckyLikey if it works for you, consider leaving an upvote and/or closing your question as resolved !
– trichetriche
yesterday
1
Exactly. And to explain the difference,combineLatest
as static (non-pipeable) signature take at least 2 observables, whilecombineLatest
as instance method can take only one (the second one being the "piped" first observable). See this stackblitz to see the difference in syntax !
– trichetriche
yesterday
|
show 7 more comments
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
4
down vote
accepted
the following is the cleanest way to handle that (according to me) :
source.pipe(
tap(val => doAnyway(val)),
switchMap(val => val.id ? of(val.id) : this.idService.getDefault())
).subscribe(id => {
this.id = id;
doSomething(id);
});
You can see how short and clear this is, and it does the exact same thing your first code was doing.
could I also provide a mapping function to map the result ofthis.idService.getDefault()
if the result wasn't an Id itself?
– LuckyLikey
yesterday
Sure,this.idService.getDefault().pipe(map(...))
(you can use pipes within pipes, there's no issue with that)
– trichetriche
yesterday
you must truly be my captain :) Addedimport 'rxjs/add/observable/of';
but it doesn't seem to be found. Im using angular 6
– LuckyLikey
yesterday
@LuckyLikey if it works for you, consider leaving an upvote and/or closing your question as resolved !
– trichetriche
yesterday
1
Exactly. And to explain the difference,combineLatest
as static (non-pipeable) signature take at least 2 observables, whilecombineLatest
as instance method can take only one (the second one being the "piped" first observable). See this stackblitz to see the difference in syntax !
– trichetriche
yesterday
|
show 7 more comments
up vote
4
down vote
accepted
the following is the cleanest way to handle that (according to me) :
source.pipe(
tap(val => doAnyway(val)),
switchMap(val => val.id ? of(val.id) : this.idService.getDefault())
).subscribe(id => {
this.id = id;
doSomething(id);
});
You can see how short and clear this is, and it does the exact same thing your first code was doing.
could I also provide a mapping function to map the result ofthis.idService.getDefault()
if the result wasn't an Id itself?
– LuckyLikey
yesterday
Sure,this.idService.getDefault().pipe(map(...))
(you can use pipes within pipes, there's no issue with that)
– trichetriche
yesterday
you must truly be my captain :) Addedimport 'rxjs/add/observable/of';
but it doesn't seem to be found. Im using angular 6
– LuckyLikey
yesterday
@LuckyLikey if it works for you, consider leaving an upvote and/or closing your question as resolved !
– trichetriche
yesterday
1
Exactly. And to explain the difference,combineLatest
as static (non-pipeable) signature take at least 2 observables, whilecombineLatest
as instance method can take only one (the second one being the "piped" first observable). See this stackblitz to see the difference in syntax !
– trichetriche
yesterday
|
show 7 more comments
up vote
4
down vote
accepted
up vote
4
down vote
accepted
the following is the cleanest way to handle that (according to me) :
source.pipe(
tap(val => doAnyway(val)),
switchMap(val => val.id ? of(val.id) : this.idService.getDefault())
).subscribe(id => {
this.id = id;
doSomething(id);
});
You can see how short and clear this is, and it does the exact same thing your first code was doing.
the following is the cleanest way to handle that (according to me) :
source.pipe(
tap(val => doAnyway(val)),
switchMap(val => val.id ? of(val.id) : this.idService.getDefault())
).subscribe(id => {
this.id = id;
doSomething(id);
});
You can see how short and clear this is, and it does the exact same thing your first code was doing.
answered yesterday
trichetriche
23.5k41949
23.5k41949
could I also provide a mapping function to map the result ofthis.idService.getDefault()
if the result wasn't an Id itself?
– LuckyLikey
yesterday
Sure,this.idService.getDefault().pipe(map(...))
(you can use pipes within pipes, there's no issue with that)
– trichetriche
yesterday
you must truly be my captain :) Addedimport 'rxjs/add/observable/of';
but it doesn't seem to be found. Im using angular 6
– LuckyLikey
yesterday
@LuckyLikey if it works for you, consider leaving an upvote and/or closing your question as resolved !
– trichetriche
yesterday
1
Exactly. And to explain the difference,combineLatest
as static (non-pipeable) signature take at least 2 observables, whilecombineLatest
as instance method can take only one (the second one being the "piped" first observable). See this stackblitz to see the difference in syntax !
– trichetriche
yesterday
|
show 7 more comments
could I also provide a mapping function to map the result ofthis.idService.getDefault()
if the result wasn't an Id itself?
– LuckyLikey
yesterday
Sure,this.idService.getDefault().pipe(map(...))
(you can use pipes within pipes, there's no issue with that)
– trichetriche
yesterday
you must truly be my captain :) Addedimport 'rxjs/add/observable/of';
but it doesn't seem to be found. Im using angular 6
– LuckyLikey
yesterday
@LuckyLikey if it works for you, consider leaving an upvote and/or closing your question as resolved !
– trichetriche
yesterday
1
Exactly. And to explain the difference,combineLatest
as static (non-pipeable) signature take at least 2 observables, whilecombineLatest
as instance method can take only one (the second one being the "piped" first observable). See this stackblitz to see the difference in syntax !
– trichetriche
yesterday
could I also provide a mapping function to map the result of
this.idService.getDefault()
if the result wasn't an Id itself?– LuckyLikey
yesterday
could I also provide a mapping function to map the result of
this.idService.getDefault()
if the result wasn't an Id itself?– LuckyLikey
yesterday
Sure,
this.idService.getDefault().pipe(map(...))
(you can use pipes within pipes, there's no issue with that)– trichetriche
yesterday
Sure,
this.idService.getDefault().pipe(map(...))
(you can use pipes within pipes, there's no issue with that)– trichetriche
yesterday
you must truly be my captain :) Added
import 'rxjs/add/observable/of';
but it doesn't seem to be found. Im using angular 6– LuckyLikey
yesterday
you must truly be my captain :) Added
import 'rxjs/add/observable/of';
but it doesn't seem to be found. Im using angular 6– LuckyLikey
yesterday
@LuckyLikey if it works for you, consider leaving an upvote and/or closing your question as resolved !
– trichetriche
yesterday
@LuckyLikey if it works for you, consider leaving an upvote and/or closing your question as resolved !
– trichetriche
yesterday
1
1
Exactly. And to explain the difference,
combineLatest
as static (non-pipeable) signature take at least 2 observables, while combineLatest
as instance method can take only one (the second one being the "piped" first observable). See this stackblitz to see the difference in syntax !– trichetriche
yesterday
Exactly. And to explain the difference,
combineLatest
as static (non-pipeable) signature take at least 2 observables, while combineLatest
as instance method can take only one (the second one being the "piped" first observable). See this stackblitz to see the difference in syntax !– trichetriche
yesterday
|
show 7 more comments
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53372350%2frxjs-conditional-nesting-observables%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown