财产&#39;做&#39;在类型&#39; Observable <iproduct []>&#39;上不存在

时间:2018-05-07 07:30:01

标签: angular rxjs6

升级到Angular 6.0并将Rxjs升级到6.0后,我收到以下编译错误:

Property 'do' does not exist on type 'Observable'.

以下是代码:

import { Observable, of } from 'rxjs';
import 'rxjs/add/operator/do';
import 'rxjs/add/observable/throw';
import 'rxjs/add/operator/catch';
import { IProduct } from './product';

@Injectable()
export class ProductService { 
    constructor(
        private product: IProduct)
    {         
    }

    getProduct = () => { 
        return product.products
            // error on next line
            .do(data => console.log('All:' + JSON.stringify(data)))
            .catch(this.handleError);
    }

    private handleError(err: HttpErrorResponse) { 
        console.log(err.message);
        return Observable.throw(err.message);        
    }
}

有什么想法吗?

4 个答案:

答案 0 :(得分:64)

问题不在于角度,而在于rxjs。 rxjs引入了rxjs版本6的重大更改。

要在不更改任何代码的情况下重新运行代码,请安装以下软件包:

npm install rxjs-compat@6 --save

然后您应该能够编译您的项目。 rxjs-compat旨在成为临时解决方案,因此您需要更新代码库以使用新版本。

新导入路径

您需要更新的内容:

  1. 更新导入语句

    import { Observable } from "rxjs/Observable";

    import { Observable } from "rxjs";

  2. 更新您的运营商导入

    import 'rxjs/add/operator/do'

    import { do } from "rxjs/operators";

  3. 重命名运算符

    由于与JavaScript保留字的名称冲突,某些运算符也已重命名。他们是

    1. do =&gt; tap

    2. catch =&gt; catchError

    3. switch =&gt; switchAll

    4. finally =&gt; finalize

    5. 无操作员链接

      然后,您也无法使用pipe运算符链接您的运算符,例如

      // an operator chain
      source
        .map(x => x + x)
        .mergeMap(n => of(n + 1, n + 2)
          .filter(x => x % 1 == 0)
          .scan((acc, x) => acc + x, 0)
        )
        .catch(err => of('error found'))
        .subscribe(printResult);
      
      // must be updated to a pipe flow
      source.pipe(
        map(x => x + x),
        mergeMap(n => of(n + 1, n + 2).pipe(
          filter(x => x % 1 == 0),
          scan((acc, x) => acc + x, 0),
        )),
        catchError(err => of('error found')),
      ).subscribe(printResult);
      

答案 1 :(得分:11)

Rxjs 6引入了一些重大变化,“do”运算符已被“tap”运算符替换(来自“rxjs/internal/operators”)。

您可以使用new运算符重构代码,或者仍然使用旧的'do'语法,通过添加rxjs-compat库以实现向后兼容性(npm install --save rxjs-compat)。

请注意,在RxJs 6之前,您必须导入'do'运算符:

import 'rxjs/add/operator/do';

此处有更多详情:Angular HTTP GET with TypeScript error http.get(...).map is not a function in [null]

答案 2 :(得分:4)

我感谢Tjaart van der Walt关于如何解决Angular / rxjs7 ++中引入的“重大更改”的答复。但是在尝试将他的响应应用于我的Angular拦截器时,我仍然遇到一些问题:

这是更新后的代码(编译失败的部分标记为“旧”)

import {Injectable} from '@angular/core';
import {HttpEvent, HttpInterceptor, HttpResponse} from '@angular/common/http';
import {HttpHandler, HttpRequest, HttpErrorResponse} from '@angular/common/http';

/*
  OLD:
  import {Observable} from 'rxjs/Observable';
  import 'rxjs/add/operator/do';
 */
import { Observable } from 'rxjs';
import { of } from 'rxjs';
import { tap, catchError } from 'rxjs/operators';

import { AuthService } from './auth.service';

@Injectable()
export class StockAppInterceptor implements HttpInterceptor {

  constructor(private authService: AuthService) {}

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    if (this.authService.authToken) {
      const authReq = req.clone({
        headers: req.headers.set(
          'Authorization',
          this.authService.authToken
        )
      });
      console.log('Making an authorized request');
      req = authReq;
    }
    /*
     * OLD:
     * return next.handle(req)
     *   .do(event => this.handleResponse(req, event),
     *      error => this.handleError(req, error));
     */
    return next.handle(req).pipe(
      tap(
        event => this.handleResponse(req, event),
        error => this.handleError(req, error)
      )
    );
  }


  handleResponse(req: HttpRequest<any>, event) {
    console.log('Handling response for ', req.url, event);
    if (event instanceof HttpResponse) {
      console.log('Request for ', req.url,
          ' Response Status ', event.status,
          ' With body ', event.body);
    }
  }

  handleError(req: HttpRequest<any>, event) {
    console.error('Request for ', req.url,
          ' Response Status ', event.status,
          ' With error ', event.error);
  }
}

所需的更改包括更改import路径以及替换pipe()tap()of()

此链接也是RxJS6更改的好资源:

https://www.academind.com/learn/javascript/rxjs-6-what-changed/

答案 3 :(得分:3)

在rxjs 6中,“ do”运算符已替换为“ tap”运算符,这就是为什么 发生此错误“类型上不存在属性“ do” 'Observable '“

要解决此错误,您有两个选择

解决方案1:修补您的代码...可以与do运算符一起正常工作

npm install rxjs-compat@6 --save

解决方案2:将您的 next.handle 代码替换为以下代码

 return next.handle(req).pipe(
      tap(
        event => this.handleResponse(req, event),
        error => this.handleError(req, error)
      )
    );