5

THE PROBLEM:

I have an interceptor:

@Injectable()
export class AuthInterceptor implements HttpInterceptor {

  constructor(private injector: Injector, private router: Router) {
  }


  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

    const auth = this.injector.get(AuthenticationService);
    const authHeaders = auth.getAuthHeader();
    const authReq = request.clone({headers: authHeaders});

     return next.handle(authReq).do((event: HttpEvent<any>) => {
       if (event instanceof HttpResponse) {

       }
     }, (err: any) => {
       if (err instanceof HttpErrorResponse) {
         if (err.status === 403) {
           this.router.navigate(['login']);
         }
       }
     });
  }
}

it was wornking in Angular 5, but now i've migrated to 6 and this doesn't work anymore.

It says property 'do' doesn't exist on type Observable.

Also i've tried to implement the solution from this thread: LINK Didn't work as well.

This topic says it is consequence of rxjs changes. After making suggested changes the problem remains (now with 'tap' instead 'do')

here is import section:

// import {Observable} from "rxjs/Observable";
import {Observable} from "rxjs/Rx";
import { tap } from 'rxjs/operators';

Note: commented line has been tried as well.

Unknwn Artist
  • 430
  • 5
  • 17
  • `Does not work` is a bit vague... Does it go through your error handler? In the 1st `if`? In the 2nd one? – David Jun 05 '18 at 08:25
  • @David, added more details. – Unknwn Artist Jun 05 '18 at 08:29
  • Possible duplicate of [Property 'do' does not exist on type 'Observable'](https://stackoverflow.com/questions/50209119/property-do-does-not-exist-on-type-observableiproduct) – David Jun 05 '18 at 08:32

4 Answers4

1

To get this working for my project (Angular 6, RxJS 6) I had to make the following changes:

import { Injectable } from '@angular/core';
import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor, HttpResponse, HttpErrorResponse } from '@angular/common/http';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
import { Router } from '@angular/router';

And modify the snippet from above to be:

(chaining changed to piping, and changed 'do' to 'tap')

@Injectable()
export class AuthInterceptor implements HttpInterceptor {

  constructor(private injector: Injector, private router: Router) {
  }


  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

    const auth = this.injector.get(AuthenticationService);
    const authHeaders = auth.getAuthHeader();
    const authReq = request.clone({headers: authHeaders});

     return next.handle(authReq).pipe(
       tap((event: HttpEvent<any>) => {
         if (event instanceof HttpResponse) {

         }
       }, (err: any) => {
         if (err instanceof HttpErrorResponse) {
           if (err.status === 403) {
             this.router.navigate(['login']);
           }
         }
       })
   );
  }
}

The reason for this are some recent changes in RxJS 6.

Use piping instead of chaining as new operator syntax. The result of one operator is piped into another operator.

And

Note Some operators have a name change due to name collisions with JavaScript reserved words! These include: do -> tap, catch -> catchError, switch -> switchAll, finally -> finalize.

Jbrown
  • 667
  • 9
  • 8
0

If your error is property 'do' doesn't exist on type Observable, try importing the operator. Put this on top of your file:

import 'rxjs/add/operator/do';
Zlatko
  • 18,936
  • 14
  • 70
  • 123
  • 1
    @UnknwnArtist check your `package.json` file, and please tell us which version of `rxjs` you use? Version 5 doesn't work with Angular 6, hence you'll have to update your `rxjs` to the latest version. Try `import { do } from rxjs/operators`, and let me know if it works. You can also use [this](https://github.com/ReactiveX/rxjs/blob/master/docs_app/content/guide/v6/migration.md) reference – mutantkeyboard Jun 05 '18 at 08:53
  • 1
    @mutantkeyboard, "rxjs": "^6.0.0", "rxjs-compat": "^6.2.0". These are from package.json. Import of "do" doesn't help. – Unknwn Artist Jun 05 '18 at 08:57
  • Ah yes, `do` has been changed to `tap`, since `do` is reserved keyword in JS. [Refer here](https://www.learnrxjs.io/operators/utility/do.html) – mutantkeyboard Jun 05 '18 at 09:00
  • @mutantkeyboard i've change "do" to "tap" now it says that property "tap" doesn't exist on Observable :) – Unknwn Artist Jun 05 '18 at 09:19
  • Could you provide us a piece of code with RXSJ related imports? – mutantkeyboard Jun 05 '18 at 10:41
  • @mutantkeyboard `// import {Observable} from "rxjs/Observable"; import {Observable} from "rxjs/Rx"; import { tap, of } from 'rxjs/operators';` commented section has been tried as well – Unknwn Artist Jun 05 '18 at 12:39
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/172517/discussion-between-mutantkeyboard-and-unknwn-artist). – mutantkeyboard Jun 05 '18 at 13:37
0

Faced same issue, here is how I have resolved

  1. ng update (To update all packages and make it compatible with angular 6)
  2. npm install rxjs-compat@6 --save (Install a updated version of rxjs)
  3. replace following functions throughout the code because they are updated in rxjs

    do => tap, catch => catchError, switch => switchAll, finally => finalize

for more information check the rxjs change-log.

Prabhu Tiwari
  • 109
  • 1
  • 7
  • Did the steps, and still i have property 'tap' doesn't exist on Observable. And another observation - whenever i execute "npm install rxjs-compat@6 --save" angular material modules need to be reinstalled. – Unknwn Artist Jun 05 '18 at 10:15
  • Make sure you are importing it right import { Observable } from 'rxjs/Observable'; import { tap } from 'rxjs/operators'; – Prabhu Tiwari Jun 05 '18 at 10:55
0

SOLUTION:

  1. run 'npm install rxjs-compat@6 --save';
  2. imports should look like this:
import {Observable} from 'rxjs';

import 'rxjs/add/operator/do';
  1. in my case there was NO NEED to change 'do' -> 'tap';

  2. if angular material is used, reinstall might be necessary after running the first command.

Unknwn Artist
  • 430
  • 5
  • 17