RXJS combineLatest issue after upgarde 5 to 6

Viewed 934

Service.ts file

Version 5 code:

return this.connectionListStoreService.connections$.pipe(
  combineLatest(this.isLoadPending$),
  filter(([connections, isPending]) => !isPending),
  map(([connections]) => connections),
  combineLatest(
    this.adapterStoreService.adapters$,
    this.applicationsStoreService.applications$
  ),
  map(([connections, adapters, applications]) => {
    if (!connections || !adapters || !applications) {
      return;
    }

    return connections
      .filter(connection => connection.source && connection.destination)
      .map((connection) => ({
        ...connection,
        source: {
          ...connection.source,
          adapter: adapters.find((item) => item.id === connection.source.appTypeId),
          application: applications.find((item) => item.id === connection.source.applicationId)
        },
        destination: {
          ...connection.destination,
          adapter: adapters.find((item) => item.id === connection.destination.appTypeId),
          application: applications.find((item) => item.id === connection.destination.applicationId)
        }
      }))
      .filter(({ source, destination }) =>
        source.application && source.adapter && destination.application && destination.adapter);
  })
);

Version 6 code:

return combineLatest([this.connectionListStoreService.connections$, this.isLoadPending$]).pipe(
  filter(([connections, isPending]) => !isPending),
  map(([connections]) => connections),
  combineLatest([this.adapterStoreService.adapters$, this.applicationsStoreService.applications$]),
  map(([connections, adapters, applications]) => {
    if (!connections || !adapters || !applications) {
      return;
    }

    return connections
      .filter(connection => connection.source && connection.destination)
      .map((connection) => ({
        ...connection,
        source: {
          ...connection.source,
          adapter: adapters.find((item) => item.id === connection.source.appTypeId),
          application: applications.find((item) => item.id === connection.source.applicationId)
        },
        destination: {
          ...connection.destination,
          adapter: adapters.find((item) => item.id === connection.destination.appTypeId),
          application: applications.find((item) => item.id === connection.destination.applicationId)
        }
      }))
      .filter(({ source, destination }) =>
        source.application && source.adapter && destination.application && destination.adapter);
  })
)

I modified this old code to new code some online guidelines. I am facing the issue in nested combineLatest in this function:

Error:

@deprecated — resultSelector no longer supported, pipe to map instead

Argument of type 'Observable<[AdapterModel[], ApplicationModel[]]>' is not assignable to parameter of type 'OperatorFunction<unknown, unknown>'.

Type 'Observable<[AdapterModel[], ApplicationModel[]]>' provides no match for the signature '(source: Observable): Observable'.ts(2345)

Version of RXJS : "6.6.3",

Let me know the is there any additional information needed from my side. Thanks in advance.

2 Answers

Are you sure you're importing the correct combineLatest? You need to import one from rxjs and another one from rxjs/operators:

import { combineLatest as combineLatestWith } from 'rxjs';
import { combineLatest } from 'rxjs/operators';

...

combineLatestWith([...]).pipe(
  ...
  combineLatest([...]),
)

I know, it's pretty confusing and it's about to change again in RxJS 7.

Btw, there used to be official migration doc here that was removed from the repo's master branch for some reason: https://github.com/ReactiveX/rxjs/blob/6.x/docs_app/content/guide/v6/migration.md

You could try to replace the combineLatest operator with the withLatestFrom, but looking at your stream, I'd make the following changes. I'd start with the isPending$ observable and switch using switchMap operator and combine multiple observables using the combineLatest function.

Try the following

import { combineLatest } from 'rxjs';
import { filter, switchMap, map } from 'rxjs/operators';

return this.isPending$.pipe(
  filter(isPending => !isPending),
  switchMap(_ => 
    combineLatest(
      this.connectionListStoreService.connections$,
      this.adapterStoreService.adapters$,
      this.applicationsStoreService.applications$
    )
  ),
  map(([connections, adapters, applications]) => {
    ...
  })
);

Here the combineLatest function from RxJS v6+ is used instead of the old combineLatest operator.

Related