我有一个Ionic应用,其user
提供商使用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();
});
}
由于某种原因,此代码从不调用成功回调,只调用错误处理程序。如果是这样,会导致您在上面的评论中看到的错误。
我的user.signup()
方法如下所示:
signup(accountInfo: any) {
return this.api.post('register', accountInfo).share();
}
我的Api
课程如下:
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);
}
}
我尝试从share()
删除user.signup()
,然后返回Observable<any>
,但这没有帮助。
答案 0 :(得分:13)
我在使用generator-jhipster-ionic(yo jhipster-ionic give v3.1.2)创建一个新项目时遇到了这个问题,在Matt Raible的(OP)Use Ionic for JHipster to Create Mobile Apps with OIDC Authentication博客文章之后,但是选择了JWT身份验证而不是OIDC。
问题的根源是各种各样的问题。
在使用livereload服务器运行Ionic应用程序时出现问题,CORS问题正在发生,Angular HTTP返回经典HTTP failure response for (unknown url): 0 Unknown Error
,其中0是HTTP错误代码。
但是,在当前情况下,Observable级别的错误处理会隐藏该问题。
当您按照Angular's HttpClient #Error Details部分建议,并在HTTP POST调用上添加带有catchError运算符的Observable管道时,您可以获得正确的HTTP错误详细信息。在这种情况下,而不是转到rxjs/util/subscribeToResult.js:71
(TS source #L80)TypeError: You provided 'undefined' where a stream was expected
默认错误情况,而是转到rx/util/subscribeToResult.js:23
(TS source #L34),错误在管道方法中正确处理。
在跟踪Observable调用之后,我发现当前的默认身份验证拦截器,如此模板src/providers/auth/auth-interceptor.ts中所示,捕获HTTP错误401并且对其他人没有任何作用,基本上将它们静音并阻止它们传播。
TL; DR 在JWT案例中,解决方案是简单地移除src/providers/auth/auth-interceptor.ts
.catch(...)
块,允许错误传播到login.service.ts
,并在其中this.authServerProvider.login(credentials).subscribe((data) => { ... }, (err) => { ... })
错误回调。
我认为问题和解决方案可能与您的OIDC案例,注册方法和错误回调相同。
[编辑]更多,因为在第一篇帖子评论中提到的首发示例中可以找到相同的.catch
代码:ionic-jhipster-starter - auth-interceptor.ts#L31
答案 1 :(得分:3)
在我的情况下,我的回归是空的:
if (...)
return; // problem here
要修复,我返回了观察对象:
if (...)
return req.next();
答案 2 :(得分:1)
我确实遇到了这个问题,在我的情况下responseType
假设是text
(因为设计的API终点)而非默认json
。
import { HttpClient } from '@angular/common/http';
在:
getToken(tokenCommand) {
return this.http.post(API_BASE_URL + 'user/token', tokenCommand);
}
修好后:
getToken(tokenCommand) {
return this.http.post(API_BASE_URL + 'user/token', tokenCommand
, { responseType: 'text' });
}
我认为此错误消息过于笼统,如果开发人员可以提供更多详细信息/有用的错误消息,那就太好了。感谢。
答案 3 :(得分:1)
对我来说,我订阅了 takeUntil
这样的订阅:
this.route.queryParams
.pipe(takeUntil(this.ngUnsubscribe))
.subscribe(async(queryParams) => {
});
我忘记用可观察对象初始化 this.ngUnsubscribe
。当我在组件 (ngUnsubscribe = new Subject()
) 中将该值设置为 observable 时,错误消失了。
答案 4 :(得分:0)
这里解决了正确的方法:)
尝试使用JSON Web Token对用户进行身份验证时,我一直面临这个问题。就我而言,它与身份验证拦截器有关。
发送对用户进行身份验证的请求并不需要提供令牌,因为它尚不存在。
检查你的拦截器是否包括:
if (req.headers.get('No-Auth') == "True")
return next.handle(req.clone());
并且您提供了{'No-Auth':'True'}
标题的请求,如下所示:
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});
}
答案 5 :(得分:0)
就我而言,该错误是由另一个问题引起的。
我在两个不同的方面提供服务。我写过:
@Injectable({provideIn: 'root'})
,我也在app.module.ts
中提供了该模块。因此,如果您遇到此错误,可以在继续操作之前进行检查
答案 6 :(得分:0)
发生在手表模式下的单元测试。 停止构建,再次触发它=错误消失了。
答案 7 :(得分:0)
我有相同的错误,典型的情况是我根据特定条件返回了不同的动作。但是缺少对一种情况的处理,因此我并没有退还任何东西。那时就是这个问题。最好使用默认的return操作来避免此类情况。
...mergeMap((res: FetchWorkflowStatusResponse) => {
if(this){
return action1
} else if(that){
return action2
}
}
现在,如果出现this
和that
以外的其他值,则将没有任何return
语句,并且会引发错误。
答案 8 :(得分:0)
就我而言,我忽略了以NgRx效果返回一个动作。我有一条条件语句,它只在一个条件下返回一个动作。
答案 9 :(得分:0)
就我而言,该错误是由另一个问题引起的。
我在两个不同的方面提供服务。我写过:
@Injectable({provideIn:'root'}) 而且我还在app.module.ts中提供了该模块。因此,如果您遇到此错误,可以在继续操作之前进行检查
答案 10 :(得分:0)
我在 Angular 中使用了 ngrx 来存储令牌。我在interceptor.ts
中遇到了此错误。
错误的代码是这样的:
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
this._store
.pipe(
select(fromSelectors.selectAuth),
)
.subscribe((state: fromReducers.AuthState) => {
if (state.token != null) {
const clonedReq = req.clone({
headers: req.headers.set('Authorization', 'Bearer ' + state.token)
});
return next.handle(clonedReq);
}
else {
this.router.navigate(['login']);
}
});
}
我通过返回流程固定了代码:
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return this._store
.pipe(
select(fromSelectors.selectAuth),
switchMap((state: fromReducers.AuthState) => {
if (state.token != null) {
const clonedReq = req.clone({
headers: req.headers.set('Authorization', 'Bearer ' + state.token)
});
return next.handle(clonedReq);
}
else {
this.router.navigate(['login']);
// return EMPTY stream
return of({}) as Observable<HttpEvent<any>>;
}
})
);
}