user8713457
user8713457

Reputation: 85

Angular v6, rxjs v6 error TS2339: Property 'pipe' does not exist on type 'OperatorFunction

I have updated code that worked fine with Angular 5.5/rxJS5.5 using the new pipe method to Angular 6/rxJS6 using the rxjs-lint package and the following commands

npm i -g rxjs-tslint
rxjs-5-to-6-migrate -p tsconfig.json

Imports etc have been amended as expected but now the code that worked fine with v5 of Angular/5.5 of RxJS is erroring with the error:

 error TS2339: Property 'pipe' does not exist on type 'OperatorFunction<{}, {} | RouterEvent | RouteConfigLoadStart | RouteConfigLoadEnd | ChildActivati...'.

I have removed the rxjs6-compat package but it makes no difference. It's almost as if the build thinks it's got an earlier version of rxJS than v5.5. package.json used with npm install looks like this...

"dependencies": {
    "@angular/animations": "^6.0.2",
    "@angular/cdk": "^6.0.2",
    "@angular/common": "^6.0.2",
    "@angular/compiler": "^6.0.2",
    "@angular/core": "^6.0.2",
    "@angular/flex-layout": "^6.0.0-beta.15",
    "@angular/forms": "^6.0.2",
    "@angular/http": "^6.0.2",
    "@angular/material": "^6.0.2",
    "@angular/platform-browser": "^6.0.2",
    "@angular/platform-browser-dynamic": "^6.0.2",
    "@angular/router": "^6.0.2",
    "@ngrx/effects": "^6.0.0-beta.3",
    "@ngrx/entity": "^6.0.0-beta.3",
    "@ngrx/router-store": "^6.0.0-beta.3",
    "@ngrx/store": "^6.0.0-beta.3",
    "@ngrx/store-devtools": "^6.0.0-beta.3",
    "@ngx-translate/core": "^9.0.1",
    "core-js": "^2.5.2",
    "hammerjs": "^2.0.8",
    "lodash": "^4.17.4",
    "material-design-icons-iconfont": "^3.0.3",
    "nsp": "^3.2.1",
    "passport": "^0.4.0",
    "passport-azure-ad": "^3.0.12",
    "rxjs": "^6.1.0",
    "zone.js": "^0.8.26"
  },

The import for rxjs operators are in rxjs6 format:

import { filter, map, merge, mergeMap } from 'rxjs/operators';

The statement that worked but now gives this error is:

// Change page title on navigation or language change, based on route data
merge(this.translateService.onLangChange, onNavigationEnd)
  .pipe(
    map(() => {
      let route = this.activatedRoute;
      while (route.firstChild) {
        route = route.firstChild;
      }
      return route;
    }),
    filter(route => route.outlet === 'primary'),
    mergeMap(route => route.data)
  )
  .subscribe(event => {
    const title = event['title'];
    if (title) {
      this.titleService.setTitle(this.translateService.instant(title));
    }
  });

What have I missed? Why is the pipe causing this error now where it was fine with rxJS 5.5?

Upvotes: 8

Views: 14956

Answers (4)

Flavien Volken
Flavien Volken

Reputation: 21309

You have 2 kind of operators

Observables:

  • imported from 'rxjs' (formerly from 'rxjs/observable')
  • they return an observable you can pipe
  • they will be used at the beginning of the chain (never within a pipe)

Operators:

  • imported from 'rxjs/operators'
  • they return an operator you will use within a pipe
  • being an operator, there is no way to call .pipe on it, or you get the TS2339: Property 'pipe' does not exist on type 'OperatorFunction error

The trap: some operators have the same name as an observable operator

For example:

import { combineLatest } from 'rxjs';
// This is the observable, you can `.pipe` it
combineLatest([a$,b$]).pipe(map(([a,b])=>{...}))
import { combineLatest } from 'rxjs/operators';
// This is the operator, it must be within a pipe.
// To prevent this ambiguity, this `combineLatest` is deprecated in rxjs7
// It has been renamed `combineLatestWith`.
a$.pipe(combineLatest(b$)).pipe(map(([a,b])=>{...}))

Upvotes: 1

faety_sal
faety_sal

Reputation: 62

The merge operator should be imported from "rxjs/observable".

Like this

import { merge } from "rxjs/observable/merge";

Upvotes: 0

Schtrudell
Schtrudell

Reputation: 376

You should import merge like this:

import { merge } from 'rxjs';

Upvotes: 33

Suchith Arella
Suchith Arella

Reputation: 30

Replace

merge(this.translateService.onLangChange, onNavigationEnd).pipe(

with this

this.router.events.pipe(filter(event => event instanceof NavigationEnd), 
  map(() => {
    let route = this.activatedRoute;

Upvotes: -1

Related Questions