34

I recently updated from Angular 5 to Angular 6.

I'm getting this warning combineLatest is deprecated: resultSelector no longer supported, pipe to map instead. Rxjs is version 6.1.0, tslint is 5.10.0, Angular CLI is 6.0.0 and Typescript 2.7.2. I'm using it like this:

const a$ = combineLatest(
  this.aStore.select(b.getAuth),
  this.cStore.select(b.getUrl),
  (auth, url) => ({auth, url}),
);

I've tried it also like this:

empty().pipe(
combineLatest(...),
  ...
)

But this gives me: combineLatest is deprecated: Deprecated in favor of static combineLatest and empty is also deprecated in favor of its static version.

pjpscriv
  • 866
  • 11
  • 20
Phaze
  • 545
  • 1
  • 5
  • 14
  • you can also try a$.pipe(a$ => combineLatest(a$,b$, c$)); with import { combineLatest } **from 'rxjs'**; – Twen Nov 20 '18 at 08:38

8 Answers8

83

combineLatest is deprecated: resultSelector no longer supported, pipe to map instead

The above warning is recommending to remove the resultSelector the last function you provided in combineLatest observable and provide it as part of map operator as follows

const a$ = combineLatest(
  this.aStore.select(b.getAuth),
  this.cStore.select(b.getUrl)
);

const result$ = a$.pipe(
  map(results => ({auth: results[0], url: results[1]}))
)

UPDATE:

If you see combineLatest is deprecated: Pass arguments in a single array instead then just add []:

const a$ = combineLatest([
  this.aStore.select(b.getAuth),
  this.cStore.select(b.getUrl)
]);
    
const result$ = a$.pipe(
  map(results => ({auth: results[0], url: results[1]}))
)
Abinesh Devadas
  • 1,517
  • 13
  • 15
  • Thank you! This works but combineLatest will make an array so I have to do it like this: `const result$ = a$.pipe(map((a) => ({auth: a['0'], url: a['1']})));` – Phaze May 10 '18 at 14:38
  • 8
    Personal preference, but I much prefer a [destructuring assignment](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment) here to mapping to a new object. So like: `const result$ = a$.pipe(tap(([auth, url]) => { /* ... */ }));` – ZackDeRose Jun 05 '18 at 01:24
  • What if I wanted to use a projector function like in the old `combineLatest()`, how would I go about this? – Dev Yego Nov 09 '19 at 19:09
  • Update https://stackoverflow.com/a/67792658/5466477 – BorisD Jun 01 '21 at 16:37
12

Unfortunately you might also get that tslint error if you import combineLatest from operators:

import { combineLatest } from 'rxjs/operators';
    
combineLatest(...array);

instead of,

import { combineLatest } from 'rxjs';
    
combineLatest(...array);
Rui Marques
  • 8,567
  • 3
  • 60
  • 91
5

Unlike the deprecated versions, combineLatest accepts an Array of Observable and returns an array containing the latest values from each. Every stream has to yield in order for combineLatest to yield.

fruitType$ = combineLatest([this.entity$, this.datasetStateService.get$('Fruits')])
  .pipe(map(data => {
    const entity = data[0];
    const dataset = data[1];
    return {
       isApple: (dataset.find(ds => ds.label === 'Apple') as DataItem).id === entity.fruitId,
       isOrange: (dataset.find(ds => ds.label === 'Orange') as DataItem).id === entity.fruitId
    }
}));
jenson-button-event
  • 18,101
  • 11
  • 89
  • 155
2

In my case it's because I explicitly set generic argument, so an incorrect combineLatest overload was selected. To get rid of the warning I've changed

combineLatest<void>([
    firstObservable$,
    secondObservable$
]);

to

combineLatest([
    firstObservable$,
    secondObservable$
]).pipe(
    mapTo(undefined)
);
Valeriy Katkov
  • 33,616
  • 20
  • 100
  • 123
1

For trailing comma error, remove the comma after (auth, url) => ({auth, url})

const a$ = combineLatest(
  this.aStore.select(b.getAuth),
  this.cStore.select(b.getUrl),
  (auth, url) => ({auth, url}),  // Remove this comma.
);

For missing import error, Make sure you have imports for all the external var's or classes you are using in the file.

Example, in this case, if you havent imported combineLatest, then import it

import { combineLatest } from 'rxjs'; // For RxJS 6.x

import { combineLatest } from 'rxjs/operators'; // For RxJS 5.x
Basavaraj Bhusani
  • 5,375
  • 2
  • 16
  • 24
  • 1
    Thanks but I think I wasn't being clear. Those were not actual issues but I was just giving an example to the problem how the issues were being reported twice. I've edited my question. – Phaze May 10 '18 at 14:22
0

i used depricated combineLatest to combine those two observables this.route.paramMap + this.route.queryParamMap:

combineLatest(this.route.paramMap, this.route.queryParamMap)
  .subscribe(combined => {
    const idFollower = combined[0].get('id');
    const page = combined[1].get('page');
  })
Mo.
  • 26,306
  • 36
  • 159
  • 225
samivic
  • 1,216
  • 14
  • 13
0

I would solve that this way:

auth$ = this.aStore.select(b.getAuth);
url$ = this.cStore.select(b.getUrl);

combinedResult$ = combineLatest([this.auth$, this.url$]).pipe(
    map(([auth, url]) => ({auth, url}))
)
Prezes
  • 21
  • 3
0

This error can also be caused by passing in an array of Subscription items, instead of actual observables, lol. (I got really sloppy on this one.)

WRONG!

const foo = Foo$.subscribe(f => {
  // do something with f here
})

const bar = Bar$.subscribe(b => {
  // do something with b here
})

combineLatest([foo, bar]).subscribe(([f, b]) => {
  // do something after both foo$ and bar$ have emitted something
})

CORRECT!

const foo$ = Foo$.pipe(
  tap(f => {
    // do something with f here
  })
)

const bar$ = Bar$.pipe(
  tap(b => {
    // do something with b here
  })
)

combineLatest([foo$, bar$]).subscribe(([f, b]) => {
  // do something after both Foo$ and Bar$ have emitted something
})
Trevor
  • 13,085
  • 13
  • 76
  • 99