RxJS: SwitchMap for Array of Strings
Following use case: A user can join 0...* groups. Each group has an ID and contains 0...* posts.
I subscribe to an Observable (to get the groups of the user he joined) and this returns an array of strings (the group IDs).
const groupIds$ = of(['a', 'b', 'c']);
If I only had one I would now use switchMap and return this new observable and subscribe to it to get the posts from the group.
But so I have an array and so this isn't working. Does anyone has an idea which RxJS operator(s) can achieve this to get the posts from all groups?
Or does no operator for such use case exist and I have to do it separately at subscribe?
rxjs
add a comment |
Following use case: A user can join 0...* groups. Each group has an ID and contains 0...* posts.
I subscribe to an Observable (to get the groups of the user he joined) and this returns an array of strings (the group IDs).
const groupIds$ = of(['a', 'b', 'c']);
If I only had one I would now use switchMap and return this new observable and subscribe to it to get the posts from the group.
But so I have an array and so this isn't working. Does anyone has an idea which RxJS operator(s) can achieve this to get the posts from all groups?
Or does no operator for such use case exist and I have to do it separately at subscribe?
rxjs
I have no idea what you want to do. You want to make an Observable for each item ingroupIds$and subscribe to all of them? Or you want subscribe only to the one that emits first?
– martin
Nov 13 '18 at 16:16
The first one: I want to make an Observable for each item in groupIds$ and subscribe to all of them. As I said if I had only one I would use switchMap and subscribe to that new observable, but with an array of strings this isn't possible
– Paul
Nov 13 '18 at 16:29
add a comment |
Following use case: A user can join 0...* groups. Each group has an ID and contains 0...* posts.
I subscribe to an Observable (to get the groups of the user he joined) and this returns an array of strings (the group IDs).
const groupIds$ = of(['a', 'b', 'c']);
If I only had one I would now use switchMap and return this new observable and subscribe to it to get the posts from the group.
But so I have an array and so this isn't working. Does anyone has an idea which RxJS operator(s) can achieve this to get the posts from all groups?
Or does no operator for such use case exist and I have to do it separately at subscribe?
rxjs
Following use case: A user can join 0...* groups. Each group has an ID and contains 0...* posts.
I subscribe to an Observable (to get the groups of the user he joined) and this returns an array of strings (the group IDs).
const groupIds$ = of(['a', 'b', 'c']);
If I only had one I would now use switchMap and return this new observable and subscribe to it to get the posts from the group.
But so I have an array and so this isn't working. Does anyone has an idea which RxJS operator(s) can achieve this to get the posts from all groups?
Or does no operator for such use case exist and I have to do it separately at subscribe?
rxjs
rxjs
edited Nov 13 '18 at 16:30
Paul
asked Nov 13 '18 at 15:51
PaulPaul
677511
677511
I have no idea what you want to do. You want to make an Observable for each item ingroupIds$and subscribe to all of them? Or you want subscribe only to the one that emits first?
– martin
Nov 13 '18 at 16:16
The first one: I want to make an Observable for each item in groupIds$ and subscribe to all of them. As I said if I had only one I would use switchMap and subscribe to that new observable, but with an array of strings this isn't possible
– Paul
Nov 13 '18 at 16:29
add a comment |
I have no idea what you want to do. You want to make an Observable for each item ingroupIds$and subscribe to all of them? Or you want subscribe only to the one that emits first?
– martin
Nov 13 '18 at 16:16
The first one: I want to make an Observable for each item in groupIds$ and subscribe to all of them. As I said if I had only one I would use switchMap and subscribe to that new observable, but with an array of strings this isn't possible
– Paul
Nov 13 '18 at 16:29
I have no idea what you want to do. You want to make an Observable for each item in
groupIds$ and subscribe to all of them? Or you want subscribe only to the one that emits first?– martin
Nov 13 '18 at 16:16
I have no idea what you want to do. You want to make an Observable for each item in
groupIds$ and subscribe to all of them? Or you want subscribe only to the one that emits first?– martin
Nov 13 '18 at 16:16
The first one: I want to make an Observable for each item in groupIds$ and subscribe to all of them. As I said if I had only one I would use switchMap and subscribe to that new observable, but with an array of strings this isn't possible
– Paul
Nov 13 '18 at 16:29
The first one: I want to make an Observable for each item in groupIds$ and subscribe to all of them. As I said if I had only one I would use switchMap and subscribe to that new observable, but with an array of strings this isn't possible
– Paul
Nov 13 '18 at 16:29
add a comment |
3 Answers
3
active
oldest
votes
You can use ideally forkJoin if you know you'll have all source Observables as an array:
groupIds$.pipe(
concatMap(groups =>
const observables = groups.map(id => ...);
return forkJoin(...observables);
)
).subscribe(...);
forkJoin will emit a single array with all the results in the same order as in groupIds$.
Eventually if you don't care about the order and just want to get all the results in parallel you can use merge instead of forkJoin (I mean the "Observable creation method" called merge imported directly from rxjs. Not the merge operator from 'rxjs/operators').
forkJoin isn't working because it's only emit if the observable completes. My Observable does not complete because if new posts arriving of the group, it will be emitted. But merge seems to be working :) THANKS! Instead of concatMap I use switchMap ;)
– Paul
Nov 13 '18 at 17:28
add a comment |
Possible solution: https://www.learnrxjs.io/operators/transformation/mergemap.html.
const groupIds$ = of(['a', 'b', 'c']);
const myPromise = id =>
new Promise(resolve => resolve(something.getPostsByGroupId(id)));
const posts$ = groupIds$.pipe(
mergeMap(
id => myPromise(id),
(valueFromSource, valueFromPromise) =>
return valueFromPromise;
));
posts$.subscribe(...);
That's not working because "id" frommergeMap(id => ...)is still an array
– Paul
Nov 13 '18 at 17:15
Check my modification to see if it works.
– wannadream
Nov 13 '18 at 17:29
That would only work if I have a final value, but my observable is a stream that not complete, but I already found a solution -> stackoverflow.com/a/53286688/8971128
– Paul
Nov 13 '18 at 17:41
add a comment |
Everyone who arrives at this question, here is the answer for "switchMap for Array of strings" (thanks to martin). You only have to use 'merge' from 'rxjs' (not the operator!). Inside switchMap return merge and you are done:
groupIds$.pipe(
switchMap(groups =>
const observables = groups.map(id =>
// your function that returns the observable
return something.getObservable(id);
);
return merge(...observables);
)
).subscribe(data =>
console.log('DATA', data);
);
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
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%2f53284718%2frxjs-switchmap-for-array-of-strings%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
You can use ideally forkJoin if you know you'll have all source Observables as an array:
groupIds$.pipe(
concatMap(groups =>
const observables = groups.map(id => ...);
return forkJoin(...observables);
)
).subscribe(...);
forkJoin will emit a single array with all the results in the same order as in groupIds$.
Eventually if you don't care about the order and just want to get all the results in parallel you can use merge instead of forkJoin (I mean the "Observable creation method" called merge imported directly from rxjs. Not the merge operator from 'rxjs/operators').
forkJoin isn't working because it's only emit if the observable completes. My Observable does not complete because if new posts arriving of the group, it will be emitted. But merge seems to be working :) THANKS! Instead of concatMap I use switchMap ;)
– Paul
Nov 13 '18 at 17:28
add a comment |
You can use ideally forkJoin if you know you'll have all source Observables as an array:
groupIds$.pipe(
concatMap(groups =>
const observables = groups.map(id => ...);
return forkJoin(...observables);
)
).subscribe(...);
forkJoin will emit a single array with all the results in the same order as in groupIds$.
Eventually if you don't care about the order and just want to get all the results in parallel you can use merge instead of forkJoin (I mean the "Observable creation method" called merge imported directly from rxjs. Not the merge operator from 'rxjs/operators').
forkJoin isn't working because it's only emit if the observable completes. My Observable does not complete because if new posts arriving of the group, it will be emitted. But merge seems to be working :) THANKS! Instead of concatMap I use switchMap ;)
– Paul
Nov 13 '18 at 17:28
add a comment |
You can use ideally forkJoin if you know you'll have all source Observables as an array:
groupIds$.pipe(
concatMap(groups =>
const observables = groups.map(id => ...);
return forkJoin(...observables);
)
).subscribe(...);
forkJoin will emit a single array with all the results in the same order as in groupIds$.
Eventually if you don't care about the order and just want to get all the results in parallel you can use merge instead of forkJoin (I mean the "Observable creation method" called merge imported directly from rxjs. Not the merge operator from 'rxjs/operators').
You can use ideally forkJoin if you know you'll have all source Observables as an array:
groupIds$.pipe(
concatMap(groups =>
const observables = groups.map(id => ...);
return forkJoin(...observables);
)
).subscribe(...);
forkJoin will emit a single array with all the results in the same order as in groupIds$.
Eventually if you don't care about the order and just want to get all the results in parallel you can use merge instead of forkJoin (I mean the "Observable creation method" called merge imported directly from rxjs. Not the merge operator from 'rxjs/operators').
answered Nov 13 '18 at 16:35
martinmartin
42.6k1187127
42.6k1187127
forkJoin isn't working because it's only emit if the observable completes. My Observable does not complete because if new posts arriving of the group, it will be emitted. But merge seems to be working :) THANKS! Instead of concatMap I use switchMap ;)
– Paul
Nov 13 '18 at 17:28
add a comment |
forkJoin isn't working because it's only emit if the observable completes. My Observable does not complete because if new posts arriving of the group, it will be emitted. But merge seems to be working :) THANKS! Instead of concatMap I use switchMap ;)
– Paul
Nov 13 '18 at 17:28
forkJoin isn't working because it's only emit if the observable completes. My Observable does not complete because if new posts arriving of the group, it will be emitted. But merge seems to be working :) THANKS! Instead of concatMap I use switchMap ;)
– Paul
Nov 13 '18 at 17:28
forkJoin isn't working because it's only emit if the observable completes. My Observable does not complete because if new posts arriving of the group, it will be emitted. But merge seems to be working :) THANKS! Instead of concatMap I use switchMap ;)
– Paul
Nov 13 '18 at 17:28
add a comment |
Possible solution: https://www.learnrxjs.io/operators/transformation/mergemap.html.
const groupIds$ = of(['a', 'b', 'c']);
const myPromise = id =>
new Promise(resolve => resolve(something.getPostsByGroupId(id)));
const posts$ = groupIds$.pipe(
mergeMap(
id => myPromise(id),
(valueFromSource, valueFromPromise) =>
return valueFromPromise;
));
posts$.subscribe(...);
That's not working because "id" frommergeMap(id => ...)is still an array
– Paul
Nov 13 '18 at 17:15
Check my modification to see if it works.
– wannadream
Nov 13 '18 at 17:29
That would only work if I have a final value, but my observable is a stream that not complete, but I already found a solution -> stackoverflow.com/a/53286688/8971128
– Paul
Nov 13 '18 at 17:41
add a comment |
Possible solution: https://www.learnrxjs.io/operators/transformation/mergemap.html.
const groupIds$ = of(['a', 'b', 'c']);
const myPromise = id =>
new Promise(resolve => resolve(something.getPostsByGroupId(id)));
const posts$ = groupIds$.pipe(
mergeMap(
id => myPromise(id),
(valueFromSource, valueFromPromise) =>
return valueFromPromise;
));
posts$.subscribe(...);
That's not working because "id" frommergeMap(id => ...)is still an array
– Paul
Nov 13 '18 at 17:15
Check my modification to see if it works.
– wannadream
Nov 13 '18 at 17:29
That would only work if I have a final value, but my observable is a stream that not complete, but I already found a solution -> stackoverflow.com/a/53286688/8971128
– Paul
Nov 13 '18 at 17:41
add a comment |
Possible solution: https://www.learnrxjs.io/operators/transformation/mergemap.html.
const groupIds$ = of(['a', 'b', 'c']);
const myPromise = id =>
new Promise(resolve => resolve(something.getPostsByGroupId(id)));
const posts$ = groupIds$.pipe(
mergeMap(
id => myPromise(id),
(valueFromSource, valueFromPromise) =>
return valueFromPromise;
));
posts$.subscribe(...);
Possible solution: https://www.learnrxjs.io/operators/transformation/mergemap.html.
const groupIds$ = of(['a', 'b', 'c']);
const myPromise = id =>
new Promise(resolve => resolve(something.getPostsByGroupId(id)));
const posts$ = groupIds$.pipe(
mergeMap(
id => myPromise(id),
(valueFromSource, valueFromPromise) =>
return valueFromPromise;
));
posts$.subscribe(...);
edited Nov 13 '18 at 17:29
answered Nov 13 '18 at 16:32
wannadreamwannadream
1,4251811
1,4251811
That's not working because "id" frommergeMap(id => ...)is still an array
– Paul
Nov 13 '18 at 17:15
Check my modification to see if it works.
– wannadream
Nov 13 '18 at 17:29
That would only work if I have a final value, but my observable is a stream that not complete, but I already found a solution -> stackoverflow.com/a/53286688/8971128
– Paul
Nov 13 '18 at 17:41
add a comment |
That's not working because "id" frommergeMap(id => ...)is still an array
– Paul
Nov 13 '18 at 17:15
Check my modification to see if it works.
– wannadream
Nov 13 '18 at 17:29
That would only work if I have a final value, but my observable is a stream that not complete, but I already found a solution -> stackoverflow.com/a/53286688/8971128
– Paul
Nov 13 '18 at 17:41
That's not working because "id" from
mergeMap(id => ...) is still an array– Paul
Nov 13 '18 at 17:15
That's not working because "id" from
mergeMap(id => ...) is still an array– Paul
Nov 13 '18 at 17:15
Check my modification to see if it works.
– wannadream
Nov 13 '18 at 17:29
Check my modification to see if it works.
– wannadream
Nov 13 '18 at 17:29
That would only work if I have a final value, but my observable is a stream that not complete, but I already found a solution -> stackoverflow.com/a/53286688/8971128
– Paul
Nov 13 '18 at 17:41
That would only work if I have a final value, but my observable is a stream that not complete, but I already found a solution -> stackoverflow.com/a/53286688/8971128
– Paul
Nov 13 '18 at 17:41
add a comment |
Everyone who arrives at this question, here is the answer for "switchMap for Array of strings" (thanks to martin). You only have to use 'merge' from 'rxjs' (not the operator!). Inside switchMap return merge and you are done:
groupIds$.pipe(
switchMap(groups =>
const observables = groups.map(id =>
// your function that returns the observable
return something.getObservable(id);
);
return merge(...observables);
)
).subscribe(data =>
console.log('DATA', data);
);
add a comment |
Everyone who arrives at this question, here is the answer for "switchMap for Array of strings" (thanks to martin). You only have to use 'merge' from 'rxjs' (not the operator!). Inside switchMap return merge and you are done:
groupIds$.pipe(
switchMap(groups =>
const observables = groups.map(id =>
// your function that returns the observable
return something.getObservable(id);
);
return merge(...observables);
)
).subscribe(data =>
console.log('DATA', data);
);
add a comment |
Everyone who arrives at this question, here is the answer for "switchMap for Array of strings" (thanks to martin). You only have to use 'merge' from 'rxjs' (not the operator!). Inside switchMap return merge and you are done:
groupIds$.pipe(
switchMap(groups =>
const observables = groups.map(id =>
// your function that returns the observable
return something.getObservable(id);
);
return merge(...observables);
)
).subscribe(data =>
console.log('DATA', data);
);
Everyone who arrives at this question, here is the answer for "switchMap for Array of strings" (thanks to martin). You only have to use 'merge' from 'rxjs' (not the operator!). Inside switchMap return merge and you are done:
groupIds$.pipe(
switchMap(groups =>
const observables = groups.map(id =>
// your function that returns the observable
return something.getObservable(id);
);
return merge(...observables);
)
).subscribe(data =>
console.log('DATA', data);
);
answered Nov 13 '18 at 17:39
PaulPaul
677511
677511
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
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%2f53284718%2frxjs-switchmap-for-array-of-strings%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
I have no idea what you want to do. You want to make an Observable for each item in
groupIds$and subscribe to all of them? Or you want subscribe only to the one that emits first?– martin
Nov 13 '18 at 16:16
The first one: I want to make an Observable for each item in groupIds$ and subscribe to all of them. As I said if I had only one I would use switchMap and subscribe to that new observable, but with an array of strings this isn't possible
– Paul
Nov 13 '18 at 16:29