4

I would like to migrate my angular 4 to angular 5. I done the migration from angular 4 to angular 5, and now I have an error on my interceptor to refresh my token. I use this code to intercept all request and refresh my token if I have an 401 error :

import { Observable } from 'rxjs/Observable';
import { Injectable, Injector } from '@angular/core';
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest } from '@angular/common/http';
import { UserService } from "./user/services/user.service";
import { SpinnerService } from "angular-spinners";

@Injectable()
export class AngularInterceptor implements HttpInterceptor {
    public userService;
    public spinnerService;

    constructor(private injector: Injector) {
    }

    private applyCredentials = function (req) {
        return req.clone({
            headers: req.headers.set('Authorization', 'Bearer ' + localStorage.getItem('eb-app-token'))
        });
    };

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        this.userService = this.injector.get(UserService);
        this.spinnerService = this.injector.get(SpinnerService);

        return next.handle(this.applyCredentials(req))
            /*.do(event => {

                if (event instanceof HttpResponse) {
                    console.log(event);
                }
            })*/
            .catch((res) => {
                console.log('Token refresh');
                if (res.status === 401 || res.status === 403) {
                    return this.userService.refreshToken().first().flatMap((data: any) => {
                        console.log(data.data);
                        if (data.data !== '') {
                            localStorage.removeItem('token');
                            localStorage.setItem('token', data.data);

                            this.userService.token = localStorage.getItem('token');
                            this.userService.isAuthenticated = true;
                        } else {
                            this.userService.logOut();

                            return Observable.throw(res);
                        }

                        return next.handle(this.applyCredentials(req));
                    });
                }
                else if (res.status === 500) {
                    this.spinnerService.hide('spinner');
                    this.spinnerService.hide('spinner-search');

                    this.userService.logOut();
                }

                return Observable.throw(res);
            });
    }
}

I have this error :

ERROR in src/app/app.interceptor.ts(25,9): error TS2322: Type 'Observable<{} | HttpProgressEvent | HttpSentEvent | HttpHeaderResponse | HttpResponse<any> | Http...' is not assignable to type 'Observable<HttpEvent<any>>'.
  Type '{} | HttpProgressEvent | HttpSentEvent | HttpHeaderResponse | HttpResponse<any> | HttpUserEvent<a...' is not assignable to type 'HttpEvent<any>'.
    Type '{}' is not assignable to type 'HttpEvent<any>'.
      Type '{}' is not assignable to type 'HttpUserEvent<any>'.
        Property 'type' is missing in type '{}'.

I tried to modify different things. I read this post Observable<{}> not assignable to type Observable<SomeType[]> but I don't see the same problem...

The line 25 is :

return next.handle(this.applyCredentials(req))

UPDATE

I modified :

return next.handle(this.applyCredentials(req))

by

return <any>next.handle(this.applyCredentials(req))

and import :

import 'rxjs/add/operator/do';
import 'rxjs/add/operator/catch';
Jérémie Chazelle
  • 1,721
  • 4
  • 32
  • 70
  • Have you tried moving the contents of `applyCredentials` inside intercept? ie `req = req.clone(....)` then using that within `next.handle`? Just trying to break it down further to see the real issue. also have you seen this https://stackoverflow.com/a/45760443/885626 – Ric Nov 07 '17 at 11:13
  • @Ric I updated my post (UPDATE 3) – Jérémie Chazelle Nov 07 '17 at 13:01
  • Ok, have you stripped it down to just the pure basics: `return next.handle(req)` and see what occurs? Some users are reporting that the wrong http service was being used and after correcting it to `HttpClient` it functioned properly. – Ric Nov 07 '17 at 13:28
  • @Ric I updated my post, I added on my next.handle and I added import. – Jérémie Chazelle Nov 07 '17 at 13:40
  • I meant just get rid of `applyCredentials` and simply return the request as is, unaltered: `return next.handle(req)` – Ric Nov 07 '17 at 13:41
  • @Ric I have the same error if I use just return next.handle(req) – Jérémie Chazelle Nov 07 '17 at 13:56
  • I think there is a more fundamental issue here then, have you ensured that you are using the correct `HttpClient` service? maybe have a read https://medium.com/@ryanchenkie_40935/angular-authentication-using-the-http-client-and-http-interceptors-2f9d1540eb8 – Ric Nov 07 '17 at 14:00
  • @Ric thx for your help ! I use the correct HttpClient. If I compare with the medium post, I use .catch() – Jérémie Chazelle Nov 07 '17 at 14:19
  • got a sample app working here with error handling etc : https://angular-unfvht.stackblitz.io – Ric Nov 07 '17 at 15:21
  • Can you try this: https://stackoverflow.com/questions/47797180/refresh-token-oauth-authentication-angular-4/47797278#47797278? – Julio Guerra Dec 13 '17 at 16:03
  • Does this answer your question? [Angular HttpClient return expecting observable rather than observable](https://stackoverflow.com/questions/48401250/angular-httpclient-return-expecting-observablehttpeventany-rather-than-observ) – Pipo Jan 02 '21 at 13:31

2 Answers2

7

You are not sending an object with the expected type to your handle function. You probably can fix it quickly by parsing it as , like

return next.handle(<any> this.applyCredentials(req))

But you really should check your return types and make sure it meets the expected.

UPDATED Answer: The problem was actually with the function return value, that should be Observable<HttpEvent<any>>. The easy fix would be to cast to any like this

return <any> next.handle(this.applyCredentials(req))

But there is no guarantee that it will work, because it does not belong to the correct class.

mcrvaz
  • 662
  • 3
  • 8
0

In my case, using Angular 15 app import the interceptor from a library, the error was

Type '(request: HttpRequest, next: HttpHandler) => Observable<HttpEvent>' is not assignable to type '(req: HttpRequest, next: HttpHandler) => Observable<HttpEvent>'. Call signature return types 'Observable<HttpEvent>' and 'Observable<HttpEvent>' are incompatible.

I solved that replace the intercept return from Observable<HttpEvent<any>> to just any.

intercept(request: HttpRequest<unknown>, next: HttpHandler): any {...}
Akostha
  • 679
  • 7
  • 8