J'ai une application ionique qui a un fournisseur user
avec une méthode signup()
:
doSignup() {
// set login to same as email
this.account.login = this.account.email;
// Attempt to login in through our User service
this.user.signup(this.account).subscribe((resp) => {
this.navCtrl.Push(MainPage);
}, (err) => {
//console.log('error in signup', err);
// ^^ results in 'You provided 'undefined' where a stream was expected'
//this.navCtrl.Push(MainPage);
// Unable to sign up
let toast = this.toastCtrl.create({
message: this.signupErrorString,
duration: 3000,
position: 'top'
});
toast.present();
});
}
Pour une raison quelconque, ce code n'appelle jamais le rappel de réussite, seul le gestionnaire d'erreurs. Lorsque cela se produit, l'erreur que vous voyez dans le commentaire ci-dessus est générée.
Ma méthode user.signup()
se présente comme suit:
signup(accountInfo: any) {
return this.api.post('register', accountInfo).share();
}
Ma classe Api
se présente comme suit:
import { HttpClient, HttpParams } from '@angular/common/http';
import { Injectable } from '@angular/core';
/**
* Api is a generic REST Api handler. Set your API url first.
*/
@Injectable()
export class Api {
public static API_URL: string = 'http://localhost:8080/api';
constructor(public http: HttpClient) {
}
get(endpoint: string, params?: any, reqOpts?: any) {
if (!reqOpts) {
reqOpts = {
params: new HttpParams()
};
}
// Support easy query params for GET requests
if (params) {
reqOpts.params = new HttpParams();
for (let k in params) {
reqOpts.params.set(k, params[k]);
}
}
return this.http.get(Api.API_URL + '/' + endpoint, reqOpts);
}
post(endpoint: string, body: any, reqOpts?: any) {
return this.http.post(Api.API_URL + '/' + endpoint, body, reqOpts);
}
put(endpoint: string, body: any, reqOpts?: any) {
return this.http.put(Api.API_URL + '/' + endpoint, body, reqOpts);
}
delete(endpoint: string, reqOpts?: any) {
return this.http.delete(Api.API_URL + '/' + endpoint, reqOpts);
}
patch(endpoint: string, body: any, reqOpts?: any) {
return this.http.put(Api.API_URL + '/' + endpoint, body, reqOpts);
}
}
J'ai essayé de supprimer share()
de user.signup()
et de renvoyer Observable<any>
, mais cela n'aide pas.
J'ai rencontré ce problème lors de la création d'un nouveau projet utilisant générateur-jhipster-ionic (yo jhipster-ionic donnant v3.1.2), à la suite de Matt Raible 's (OP) Utilisez Ionic pour JHipster pour créer des applications mobiles avec OIDC Authentification article de blog, mais en choisissant l'authentification JWT au lieu de l'OIDC.
L'origine du problème était un mélange de problèmes.
J'avais le problème lors de l'exécution d'une application Ionic avec le serveur livereload, des problèmes CORS se produisant et HTTP angulaire renvoyant le HTTP failure response for (unknown url): 0 Unknown Error
classique, où 0 est le code d'erreur HTTP . Cependant, dans le cas présent, le problème était masqué par une mauvaise gestion des erreurs. au niveau observable.
Lorsque vous suivez Détails HttpClient #Error d'angular conseils de section et ajoutez un canal Observable avec un opérateur catchError sur l'appel HTTP POST, vous pouvez obtenir les détails d'erreur HTTP appropriés. Dans ce cas, au lieu de descendre au cas d’erreur par défaut rxjs/util/subscribeToResult.js:71
( source TS # L80 ) TypeError: You provided 'undefined' where a stream was expected
, il passe à rx/util/subscribeToResult.js:23
( source TS # L34 ) et l’erreur est gérée correctement dans la canalisation. méthode.
Après avoir suivi les appels Observable, j’ai constaté que l’intercepteur d’authentification par défaut actuel, comme indiqué dans ce modèle src/providers/auth/auth-interceptor.ts attrape l’erreur HTTP 401 et ne fait rien pour les autres, en les désactivant empêcher leur propagation.
TL; DR Dans le cas de JWT, la solution consiste simplement à supprimer le bloc src/providers/auth/auth-interceptor.ts
.catch(...)
, permettant ainsi la propagation d'erreur à login.service.ts
et dans son rappel d'erreur this.authServerProvider.login(credentials).subscribe((data) => { ... }, (err) => { ... })
.
Je pense que le problème et la solution pourraient être les mêmes pour votre cas OIDC, sa méthode d'inscription et le rappel d'erreur.
[Edit] Encore plus puisque le même code .catch
peut être trouvé dans l'exemple d'initiation mentionné dans le premier commentaire: ionic-jhipster-starter - auth-interceptor.ts # L31
J'ai été confronté à ce problème et dans mon cas, responseType
suppose d'être text
(en raison du point de terminaison de l'API conçu) plutôt que par défaut json
.
import { HttpClient } from '@angular/common/http';
Avant:
getToken(tokenCommand) {
return this.http.post(API_BASE_URL + 'user/token', tokenCommand);
}
Après fixé:
getToken(tokenCommand) {
return this.http.post(API_BASE_URL + 'user/token', tokenCommand
, { responseType: 'text' });
}
Je pense que ce message d'erreur est trop général et que ce serait bien si ses développeurs pouvaient fournir un message d'erreur plus détaillé/utile. Merci.
Dans mon cas, je revenais avec retour vide:
if (...)
return; // problem here
Pour réparer, j'ai retourné l'objet observé:
if (...)
return req.next();
Dans mon cas, l'erreur était due à un problème différent.
Je fournissais le service en deux points différents. J'avais écrit:
@Injectable({provideIn: 'root'})
et je fournissais également le module dans le app.module.ts
. Donc, si vous rencontrez cette erreur, vous pouvez le vérifier avant de continuer.
Il m'est arrivé de faire des tests unitaires en mode de surveillance . Arrêtez la construction, relancez-la = l'erreur est partie.
Résolu ici dans le bon sens :)
J'ai été confronté à ce problème lors de la tentative d'authentification d'un utilisateur à l'aide d'un jeton Web JSON. dans mon cas, c'est lié à l'intercepteur d'authentification.
L'envoi d'une demande d'authentification d'un utilisateur ne nécessite pas de jeton puisqu'il n'existe pas encore.
Vérifiez que votre intercepteur inclut ceci:
if (req.headers.get('No-Auth') == "True")
return next.handle(req.clone());
Et que vous fournissiez {'No-Auth':'True'}
à votre requête d'en-tête comme ceci:
authenticateUser(user): Observable<any> {
const headers = new HttpHeaders({'No-Auth':'True'});
headers.append('Content-Type', 'application/json');
return this.httpClient.post(`${this.apiEndpoint}/auth/authenticate`, user, {headers: headers});
}