I am having a problem with rxjs.
I have a function that should do this:
- Having a list of group ids. In the example:
of(['1', '2']) - For each one of them fetch the list of chats
- Return merged list of chats
When execution reaches toArray nothing happens, no result.
Code
get chats$(): Observable<Chat[]> {
return of(['1', '2']).pipe(
filter(groupIds => !!groupIds && groupIds.length > 0),
switchMap(groupIds => groupIds),
switchMap(groupId => getGroupChats(groupId)), // fetch list of chats for the group id
toArray(),
map(doubleList => {
return ([] as Chat[]).concat(...doubleList); // merge chat lists
})
);
}
I have tried this too:
get chats$(): Observable<Chat[]> {
return of(['1', '2']).pipe(
filter(groupIds => !!groupIds && groupIds.length > 0),
map(groupIds =>
groupIds.map(groupId => getGroupChats(groupId))
),
switchMap(chatList$ =>
forkJoin(chatList$).pipe(
map(doubleList => {
return ([] as Chat[]).concat(...doubleList);
})
)
)
);
}
Test
Test response is: Error: Timeout - Async callback was not invoked within 5000ms
describe("WHEN: get chats$", () => {
const CHAT_MOCK_1: Chat = {
id: "1",
};
const CHAT_MOCK_2: Chat = {
id: "2",
};
it("THEN: get chats$ should return chat list", (done) => {
service.chats$
.subscribe((data) => {
expect(data.length).toEqual(2);
expect(data[0]).toEqual(CHAT_MOCK_1);
expect(data[1]).toEqual(CHAT_MOCK_2);
done();
})
.unsubscribe();
});
});
Finally this is what I have done (and it works):
forkJointo get final emitted value of each observable of the generated Array.Code
I still have some doubts about why this works and not the previous versions, if someone could explain that would be great.
As a conclusion: do not concat multiple
switchMap.