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

后端 未结 5 1341
遇见更好的自我
遇见更好的自我 2021-02-01 02:04

After upgrading to Angular 6.0 and Rxjs to 6.0 I receive the following compilation error:

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

Her

相关标签:
5条回答
  • 2021-02-01 02:27

    I appreciate Tjaart van der Walt's response about how to resolve the "breaking changes" introduced in Angular/rxjs7++. But I still encountered several problems trying to apply his response to my Angular interceptor:

    Here is the updated code (the sections that failed to compile are marked "OLD")

    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);
      }
    }
    

    Required changes include changing import paths, and substituting pipe(), tap() and of().

    This link is also a good resource for RxJS6 changes:

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

    0 讨论(0)
  • 2021-02-01 02:34

    The problem is not with angular but with rxjs. rxjs introduced breaking changes from rxjs version 6.

    To get your code working again without changing any of your code install the following package:

    npm install rxjs-compat@6 --save

    You should then be able to compile your project. rxjs-compat is meant to be a temporarily solution so you need to update your codebase to work with the new version.


    New Import Path

    What you need to update:

    1. Update import statements from

      import { Observable } from "rxjs/Observable";

      to

      import { Observable } from "rxjs";

    2. Update your operator imports from

      import 'rxjs/add/operator/do'

      to

      import { do } from "rxjs/operators";


    Renamed Operators

    Some operators have also been renamed due to name collisions with JavaScript reserved words. They are

    1. do => tap

    2. catch => catchError

    3. switch => switchAll

    4. finally => finalize


    No Operator Chaining

    You also then can't chain your operators anymore you need to use the pipe operator e.g.

    // 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);
    
    0 讨论(0)
  • 2021-02-01 02:39

    Rxjs 6 has introduced some breaking changes and the "do" operator has been replaced by the "tap" operator (from 'rxjs/internal/operators').

    You could refactor your code using the new operator or still use the old 'do' syntax by adding the rxjs-compat library for backward compatibility (npm install --save rxjs-compat).

    Note that before RxJs 6 you had to import the 'do' operator :

    import 'rxjs/add/operator/do';
    

    More details here : Angular HTTP GET with TypeScript error http.get(...).map is not a function in [null]

    0 讨论(0)
  • 2021-02-01 02:50

    "do" operator had replaced with "tap" operator in rxjs 6 , that why this error occurs "Property 'do' does not exist on type 'Observable<IProduct[]>'"

    To Fix this Error, you have two options

    Solution 1: Patch your code ... it will work fine with do operator

    npm install rxjs-compat@6 --save
    

    Solution 2: Replace your next.handle code with below code

     return next.handle(req).pipe(
          tap(
            event => this.handleResponse(req, event),
            error => this.handleError(req, error)
          )
        );
    
    0 讨论(0)
  • 2021-02-01 02:50

    Just use in your typescript file:

    import 'rxjs/add/operator/do';
    

    as simple as that. Thanks.

    0 讨论(0)
提交回复
热议问题