45 votes

"rxjs" observable.throw n'est pas une fonction - Angular4

J'ai appris Angular 4 et tout se passait bien jusqu'à ce que j'essaie de mettre en œuvre la gestion des captures dans un service. J'essaie d'utiliser catch et throw de "rxjs" mais j'ai une erreur de fonction indéfinie dans ma console.

import { Injectable } from '@angular/core';
import { Http } from "@angular/http";
import { Observable } from 'rxjs/observable';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';
import { AppError } from "../app/common/app.error";
import { NotFoundError } from "../app/common/not-found-error";
import { BadInput } from "../app/common/bad-input";

@Injectable()
export class PostService {
  private url = "https://jsonplaceholder.typicode.com/posts";

  constructor(private http: Http) { }

 deletepost(post){
      // return this.http.delete(this.url + '/' + post.id)
      // Hard-coded id to test 404
      return this.http.delete(this.url + '/' + 93498)
        .catch((error: Response) => {
          console.log('error within catch is ' + Response)
          if(error.status === 404)
            return Observable.throw(new NotFoundError(error));

          return Observable.throw(new AppError(error));
        });
    }
}

Voici le message d'erreur :

TypeError: __WEBPACK_IMPORTED_MODULE_2_rxjs_observable__["Observable"].throw is not a function. 
(In '__WEBPACK_IMPORTED_MODULE_2_rxjs_observable__["Observable"].throw(new 
__WEBPACK_IMPORTED_MODULE_6__app_common_not_found_error__["a" /* NotFoundError 
*/](error))', 
'__WEBPACK_IMPORTED_MODULE_2_rxjs_observable__["Observable"].throw' is 
undefined) — post.service.ts:42

J'ai également cet avertissement dans mon navigateur :

./~/rxjs/Observable.js
There are multiple modules with names that only differ in casing.
This can lead to unexpected behavior when compiling on a filesystem with other case-semantic.
Use equal casing. Compare these module identifiers:
* /Users/nickgowdy/Desktop/Angular2/angular4 source code/hello-world/node_modules/rxjs/Observable.js
    Used by 14 module(s), i. e.
    /Users/nickgowdy/Desktop/Angular2/angular4 source code/hello-world/node_modules/@angular/core/@angular/core.es5.js
* /Users/nickgowdy/Desktop/Angular2/angular4 source code/hello-world/node_modules/rxjs/observable.js
    Used by 1 module(s), i. e.
    /Users/nickgowdy/Desktop/Angular2/angular4 source code/hello-world/node_modules/@ngtools/webpack/src/index.js!/Users/nickgowdy/Desktop/Angular2/angular4 source code/hello-world/src/services/post.service.ts

1 votes

Essayez d'importer import { Observable } from 'rxjs/Observable'; avec un "O" majuscule au lieu de import { Observable } from 'rxjs/observable'; avec un "o" minuscule et voir si cela fait une différence.

0 votes

@AlexanderStaroselsky Wow je ne peux pas croire que c'était la raison. Je n'ai pas remarqué que c'était une majuscule O parce que cela ne correspond pas à la convention de dénomination de toutes les autres dépendances importées. Vous devriez publier cette réponse pour que je puisse la marquer comme correcte.

0 votes

J'ai connu la même chose, l'erreur n'est pas toujours claire. Cela vous dérange si je mets cela comme réponse afin que d'autres personnes rencontrant ce problème puissent trouver une solution ?

128voto

Alexander Staroselsky Points 13670

L'erreur There are multiple modules with names that only differ in casing. indique que la mauvaise importation est ciblée avec la façon dont vous essayez d'utiliser Observable .

L'importation doit se faire avec un "O" majuscule comme :

import { Observable } from 'rxjs/Observable';

Cela importera l'individu Observable qui peut être utilisé en combinaison avec des opérateurs tels que catch o throw sur les Observables créés.

import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';

Pour importer l'objet Observable complet, vous devez l'importer comme suit :

import { Observable } from 'rxjs/Rx'

Mise à jour :

Avec les versions plus récentes de RxJS (5.5+), les opérateurs tels que map() y filter() peut être utilisé comme opérateurs de tuyauterie en combinaison avec pipe() plutôt que de les enchaîner. Ils sont importés tels que :

import { filter, map, catchError } from 'rxjs/operators';

Gardez à l'esprit des termes tels que throw sont des mots clés réservés en JavaScript, de sorte que le RxJS throw est importé en tant qu'opérateur :

import { _throw } from 'rxjs/observable/throw';

Mise à jour :

Pour les versions plus récentes de RxJS (6+), utilisez ceci :

import { throwError } from 'rxjs';

et lancer une erreur comme celle-ci :

if (error.status === 404)
    return throwError( new NotFoundError(error) )

2 votes

L'importation de l'Observable complet - import { Observable } from 'rxjs/Rx' - augmente la taille du paquet. Extrait de la documentation : github.com/ReactiveX/rxjs Pour n'importer que ce dont vous avez besoin par Parcheando (ceci est utile pour le regroupement sensible à la taille) : import { Observable } from 'rxjs/Observable' ; import 'rxjs/add/observable/of' ; import 'rxjs/add/operator/map' ;

1 votes

Oui, import { Observable } from 'rxjs/Rx'; peut augmenter de manière significative la taille du paquet car il importe l'intégralité Observable objet. Dans la plupart des cas, je dirais que ce n'est pas nécessaire, mais je voulais le fournir comme une option car chaque application est différente et peut avoir besoin de ce type de contrôle.

0 votes

@AlexanderStaroselsky vous bénir homme m'a beaucoup aidé, quelle est la différence entre import {Observable} de "rxjs/Observable et import {Observable} de "rxjs parce que j'ai eu un problème avec Observable throw(error) il a seulement fonctionné quand j'ai enlevé /Observable à la fin

30voto

Dans RxJS 6, Observable.throw() est remplacé par throwError() qui fonctionne de manière très similaire à son prédécesseur. Ainsi, vous pouvez remplacer de Observable.throw(error) à seulement throwError(error) par l'importation :

import { throwError } from 'rxjs';

Consultez ce lien pour plus de références : https://www.metaltoad.com/blog/angular-6-upgrading-api-calls-rxjs-6

1 votes

Ceci m'a sauvé ! Voici le nouveau correctif

13voto

Sibeesh Venu Points 4473

J'ai rencontré le même problème dans mon angular 5 application. Ce que j'ai fait, c'est ajouter un nouveau paquet.

import { throwError } from 'rxjs';
import { filter, map, catchError } from 'rxjs/operators';

Et de mon http l'appel de service je renvoie une fonction.

return this.http.request(request)
      .pipe(map((res: Response) => res.json()),
        catchError((res: Response) => this.onError(res)));

Et dans onError Je renvoie l'erreur avec throwError(error) .

onError(res: Response) {
    const statusCode = res.status;
    const body = res.json();
    const error = {
      statusCode: statusCode,
      error: body.error
    };
    return throwError(error);
  }

1 votes

Cette solution a fonctionné dans mon application Angular 6 avec rxjs 6.0. Mon instruction d'importation est déjà import { Observable } from 'rxjs/Observable', tout en faisant cela, j'obtiens toujours l'erreur Observable.throw is not a function. J'ai essayé d'importer 'rxjs/add/observable/throw' mais cela a donné une erreur de compilation.

1 votes

Merci Sibeesh !

4voto

Waleed Shahzaib Points 347

_throw a été supprimé dans les nouvelles versions de RxJS.
Pour les versions plus récentes de RxJS (6+), utilisez ceci :

 import { throwError } from 'rxjs'; 

et lancer une erreur comme celle-ci :

 if (error.status === 404)
    return throwError( new NotFoundError(error) )

0voto

Rob Lassche Points 467

Dans Angular9 Observable :

  1. si les données sont arrivées et que le statut est OK, alors envoyer les données
  2. Si l'ÉTAT des données n'est PAS OK, une erreur est lancée.

    myObsFunc(): Observable<any> { return this.http.get<any>('/api/something') .pipe( / Catch a backend error and let the component know / catchError( err => { / Rethrow error / return throwError( err ); }), map( (res)=> { if( res.STATUS == "OK" ) { / Send DATA to subscriber / return Object.values( res.DATA) } else { / Inform subscriber that a functional error occured / throw ( "getOrphans: Status is not OK but "+ res.STATUS ) ; }
    }), )
    }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X