Reputation: 210
I'm kinda new to rxjs (we've been stuck with angularJS for a long time and finally getting out of our technical debt).
Using angular7, I have a list of requests like this. Using forkJoin, I manage it like this :
let requests = []
for (let asset in this.assets)
{
if(asset.enabled)
requests.push(this.apiService.postAsset(oAsset))
}
return forkJoin(requests)
And it works fine, I get my array of responses. however I'm a bit stuck trying to figure out how to get different callbacks depending on asset type. I'd like something like
private saveAssets(): Observable<any>{
let requests = []
for (let asset in this.assets)
{
//asset exists already
if(asset.id)
{
requests.push(this.apiService.putAsset(asset)
.subscribe(response => {
// do something with asset
}))
}
else
{
requests.push(this.apiService.postAsset(asset)
.subscribe(response => {
asset.id = response.id
// do some more thing with asset
}))
}
}
return forkJoin(requests)
//keep the forkjoin because I want to do something when everything is done
}
But it won't work. Error given
ERROR TypeError: You provided an invalid object where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.
is related to function calling the one doing the request which looks like this (it worked fine without the single 'subscribes') :
this.saveAssets()
.subscribe(responses => {
console.log(responses)
})
Any help, or hint about thing to look for, would be much appreciated... I'll allocate more time learning RxJS but for now I'm just trying to get this small thing to work in a not-too-dirty way.
Thank you so much !
Upvotes: 0
Views: 1854
Reputation: 872
Subscribing to an observable will return Subscription. But the forkjoin will expect the array of observable. In your case this will be an array of Subscriptions. Use map operator for each request as follows to solve your issue.
let requests = []
for (let asset in this.assets)
{
//asset exists already
if(asset.id)
{
requests.push(this.apiService.putAsset(asset)
.pipe(map(response => {
// do something with asset or alter the response from here
return response;
})
));
}
else
{
requests.push(this.apiService.postAsset(asset)
.pipe(map(response => {
// do something with asset or alter the response from here
return response;
})));
}
}
return forkJoin(requests).
The Map operator applies a function of your choosing to each item emitted by the source Observable, and returns an Observable that emits the results of these function applications.
If you don't want to alter the final result, Use tap operator.
Upvotes: 4