jugglervr
jugglervr

Reputation: 175

Chaining dependent RxJs observables together?

I'm trying to chain observables that depend on api calls (that depend on data in prior observables) in order to compose an object.

I fetch a roster that has a manifest ID. From that ID, I fetch the manifest, and then compose a registry from both.

The code I'm fiddling with is below. I'm getting a type assignment error in the last concatMap.

  composeRegistry(slug:string):Observable<Registry>{
    let roster:Roster;
    const registry$ = !slug ? of(null) : this.selectRoster(slug).pipe(
      tap(res => roster = res), // storing the variable outside because I was having trouble referencing it later
      concatMap((res:Roster) => {
        return this.manifestQuery.selectManifest(res.manifest);
      }),
      concatMap((manifest:Manifest) => { // error HERE, snipped below
        let registry: Registry = {
          ...roster,
          hash: manifest.hash,
          publisher: manifest.publisher,
          url: manifest.url}
        return registry;
      })
    );
    return registry$;
  }

error:

Argument of type '(manifest: Manifest) => Registry' is not assignable to parameter of type '(value: Manifest, index: number) => ObservableInput<any>'.
  Type 'Registry' is not assignable to type 'ObservableInput<any>'.
    Property '[Symbol.iterator]' is missing in type 'Registry' but required in type 'Iterable<any>'.ts(2345)

things worked fine when I was just fetching a roster, but the dependent api call is throwing me a bit.

Upvotes: 0

Views: 405

Answers (2)

Barremian
Barremian

Reputation: 31125

I'd say you don't actually need the second concatMap. If all you wish to do is return an object of type Registry from the observable, you could pipe in a map to it. This will also remove the need for the variable let roster: Roster. Try the following

composeRegistry(slug:string): Observable<Registry> {
  const registry$ = !slug 
    ? of(null) 
    : this.selectRoster(slug).pipe(
      concatMap((roster: Roster) => 
        this.manifestQuery.selectManifest(roster.manifest).pipe(
          map((manifest: Manifest): Registry => (<Registry>{ 
            ...roster, 
            hash: manifest.hash,
            publisher: manifest.publisher,
            url: manifest.url
          }))
        )
      );
  return registry$;
}

Upvotes: 1

T. van den Berg
T. van den Berg

Reputation: 364

concatMap should return an Observable. But you return an object of type Registry. Instead of concatMap just use map(). That should fix it.

Upvotes: -1

Related Questions