0

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 !

2
  • I'm looking at the syntax and I don't see an issue here. Are you sure none of the requests are erroring out? Commented Mar 12, 2019 at 10:01
  • Hi @jriver27 and thank you ! Yup, every single call is correctly executed by the api. Commented Mar 12, 2019 at 10:05

1 Answer 1

4

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you so much ! It works ! I tried the map operator already without success but I guess my syntax was incorrect.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.