Being new to the world of RXJS, I have spent a considerable amount of time researching and seeking solutions on stackoverflow and various documentation sources before turning to ask for help here. However, despite my efforts, I am struggling to make my logic function correctly.
My current setup involves an Observable that fetches a collection of documents and makes use of the pipe operator to perform some transformations, such as utilizing the map operator to modify the objects. Everything seems to be working fine up to this point.
The issue arises when I need to send an "http request" for each document in order to retrieve specific data (referred to as "tags"). This http request is also treated as an Observable and requires subscription to fetch the necessary data. The challenge lies in the fact that the subscription process takes some time, resulting in the final object missing the required data.
let myFunction.pipe(
// mapping to add missing data needed for the front-end
map((results) => ({
...results,
documents: results._embedded.documents.map((document) => ({
...document,
tags: []
})),
})),
// mapping to loop through each document, and use the observable to get the tags with the document id
map((results) => {
let documents = results.documents.map((document: Document) => {
// get Tags for each document
let tagsToReturn = []
this.getDocumentTags(document.id)
.pipe(
// map function to return only the ids for each document, and not the complete tag object
map((tagsArray) => {
const modifiedTagsArray = tagsArray.map((tagObject: any) => {
if (tagObject !== undefined) {
return tagObject.id
}
})
return modifiedTagsArray
})
)
// the subscription to "actually" get the tags
.subscribe((tagsArray: number[]) => {
// Here the tags are found, but the latter code is executed first
// document.tags = tagsArray
tagsToReturn = tagsArray
})
// console.log(JSON.stringify(document))
// Here the tags are not found yet
console.log(JSON.stringify(tagsToReturn))
return { ...document, tags: tagsToReturn }
})
// I then, normally return the new documents with the tags for each document, but it is empty because the subscribe didn't return yet.
return {
_links: results._links,
page: results.page,
documents: documents,
}
}),
map((results) => {
results.documents.forEach((doc) => {
return this.addObservablesToDocument(doc)
})
return results
})
)
I have experimented with different approaches using operators like switchmap, forkjoin, concat, etc., but I have been unsuccessful in finding the correct solution. Therefore, I am reaching out to inquire if there is a way to resolve or manage this problem effectively.
In attempting to address the issue, I have explored options involving operators such as mergemap, concat, switchmap to transition to the new request, but encountered challenges in maintaining the global object.
I have tried to replicate/rework aspects of this approach