web-dev-qa-db-fra.com

Le type 'void' n'est pas assignable au type 'ObservableInput <{}>'

Cette erreur a commencé à apparaître après ma migration vers TS 2.2.2, alors je suppose que c'est le problème ... Le code ne s'est pas arrêté de fonctionner, mais maintenant je reçois cette erreur et j'ai essayé quelques choses comme retourner un observable vide En attrapant l'exception relancée et en renvoyant un objet, rien ne semblait fonctionner. Pourquoi cela se passe-t-il maintenant? Ne devrait-il pas comprendre que je rejette l'exception sans attendre un retour? Est-ce que je comprends mal l'erreur?

Voici la description complète de l'erreur:

enter image description here

Voici le code complet:

return request
    .map((res: Response) => res.json())
    .catch((error: any) => {
        // todo: log?

        if (error.status == 500) {
            this.alertService.showError(error.statusText);
        } else if (error.status == 588) {
            this.alertService.showAlert(error.statusText);
        }

        Observable.throw(error.statusText);
    });

J'ai essayé de renvoyer l'Observable, mais ma méthode d'emballage attend un retour de type T, qui est le retour de ma demande désérialisée (map(...)). Si je retourne la throw c'est l'erreur que je reçois:

[ts] Le type 'Observable' n'est pas assignable au type 'T'

J'utilise:

  • Angulaire4
  • TypeScript 2.2.2
39
eestein

vous devez retourner l'observable

 return request
    .map((res: Response) => res.json())
    .catch((error: any) => {
        // todo: log?

        if (error.status == 500) {
            this.alertService.showError(error.statusText);
        } else if (error.status == 588) {
            this.alertService.showAlert(error.statusText);
        }

        return Observable.throw(error.statusText);
    });
58

Parfois, lorsque vous appelez catch sans utiliser la fonction de flèche comme ci-dessous

getUserList() {
    return this.http.get(this.constURL + '/api/url/here', this.headerOptions)
    .catch(this.handleError);
}

handleError(error: Response) {
    if (error.status == 500) {      
      this.router.navigate(['/login']);
    } else {
      return Observable.throw(error);
    }
}

alors il donne une erreur de

ERREUR TypeError: Impossible de lire la propriété 'naviguer' des indéfinis sans l'obtenir

Parce que dans la fonction handleError, cet objet n'est pas accessible..Si vous consolez this.router, vous obtiendrez alors undefined .., de sorte que cet objet ne fonctionne pas et que le routeur n'obtient pas toutes les méthodes disponibles.

Donc, vous devez utiliser la fonction flèche ici comme ci-dessous

getUserList() {
    return this.http.get(this.constURL + '/api/url/here', this.headerOptions)
    .catch(error => { 
      return this.handleError(error);
    });
}

handleError(error: Response) {
    if (error.status == 500) {      
      this.router.navigate(['/login']);
    } else {
      return Observable.throw(error);
    }
}

De plus, si vous n’avez pas mentionné le retour de la fonction handlerError, il renverra une erreur comme

L'argument de type '(error: any) => void' n'est pas assignable au paramètre de type

Il est donc nécessaire de taper return pour la fonction handlerError.

Vérifiez ici pour en détail.Il a très bien expliqué le code avec toutes les erreurs possibles et la solution de cela..travaillé pour moi

7
Prashant M Bhavsar

Ceci est une réponse pour angular 6 avec RXJS 6. Dans votre fonction de requête, cela ressemblerait à ceci. Notez que catch a été remplacé par catchError et Observable.throw est maintenant throwError. De plus, dans RXJS 6, nous utilisons un tuyau pour joindre une séquence de fonctions que nous souhaitons exécuter à la place du chaînage de points précédent.

//In your service

getData(url: string): Observable<any> {
    let options = this.getHTTPOptions();
    return this.http.get<any>(url, options).pipe(
          catchError( (err: any, caught: Observable<any>) => { return 
        throwError(this.generalErrorHandler(err, caught)) } ) );
}

Ensuite, vous pouvez avoir un gestionnaire d'erreur. La clé consiste à spécifier le mot clé return dans la fonction catchError ci-dessus et à renvoyer l'erreur dans le gestionnaire. La flèche (=>) vous permet de transmettre le contexte de la fonction appelante au gestionnaire d'erreurs, ce qui signifie que vous pouvez effectuer des tâches intéressantes telles que this.router.navigate(['someroute']); (si le routeur est importé dans votre service).

//In your service

  generalErrorHandler(error: any, caught: Observable<any>): Observable<any> {
    console.log('error caught: ', error);
    if( error.error.status == "INVALID_TOKEN" || error.error.status == "MAX_TOKEN_ISSUE_REACHED"){
      console.log('token has expired');
      this.logout();
      return error;
    }
    return error;
  }

Quelques importations clés pour que cela fonctionne:

//Imports for the service

import { HttpClient, HttpHeaders, HttpErrorResponse } from '@angular/common/http';
import { Http, Response } from '@angular/http';
import { catchError, map } from 'rxjs/operators';
import { Observable, throwError, of} from 'rxjs';

Et enfin pour vous abonner à la demande pour obtenir vos données:

//In your component, don't forget to import your service

let response$ = this.someService.getData('url here');
response$.subscribe( 
    data => { console.log('do stuff to data here', data); },
    err => { console.log("couldn't get data, maybe show error to user"); },
    () => { console.log('function that is called upon finish'); }
);
5
Josh Dando