Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Property 'first' does not exist on type 'Observable<string>'

In Angular 5, I'd like to use the first() method as shown below:

this.ccService.mode.first().subscribe(mode => {
  this.mode = mode;
});

I have it imported like this: import { first } from 'rxjs/operators/first';. I've also tried importing from 'rxjs/add/operator', 'rxjs/operators', 'rxjs', none seem to work.

However, it refuses to work and only gives me the error message you already saw in the title: [ts] Property 'first' does not exist on type 'Observable<string>'..

The mode observable:

private modeSource = new BehaviorSubject<string>('new');
public mode = this.modeSource.asObservable();

public setMode(mode: string) {
  this.modeSource.next(mode);
}

I've been googling but I can't seem to find anyone with the same error, am I just not using first() right? Am I supposed to use .pipe(first()).subscribe? https://www.learnrxjs.io/operators/filtering/first.html uses observable.first().subscribe and observable.pipe(first()).subscribe intermittently without clear explanation or reasoning, so I'm a bit lost here.

like image 615
Siebe Avatar asked May 22 '18 08:05

Siebe


1 Answers

TL;DR; Yes, you should use pipeable operators.

Change since rxjs v5.5 :

The previous coding style of chaining operators has been replaced by piping the result of one operator to another. Pipeable operators were added in version 5.5. For a full discussion of the reasoning and changes required for pipeable operators, see RxJS documentation.

And here is the why :

Problems with the patched operators for dot-chaining are:

Any library that imports a patch operator will augment the Observable.prototype for all consumers of that library, creating blind dependencies. If the library removes their usage, they unknowingly break everyone else. With pipeables, you have to import the operators you need into each file you use them in.

Operators patched directly onto the prototype are not "tree-shakeable" by tools like rollup or webpack. Pipeable operators will be as they are just functions pulled in from modules directly.

Unused operators that are being imported in apps cannot be detected reliably by any sort of build tooling or lint rule. That means that you might import scan, but stop using it, and it's still being added to your output bundle. With pipeable operators, if you're not using it, a lint rule can pick it up for you.

Functional composition is awesome. Building your own custom operators becomes much, much easier, and now they work and look just like all other operators from rxjs. You don't need to extend Observable or override lift anymore.

like image 173
ibenjelloun Avatar answered Sep 20 '22 08:09

ibenjelloun