首页 文章

TypeError:您提供了'undefined',其中包含一个流

提问于
浏览
4

我有一个具有 user 提供程序和 signup() 方法的Ionic应用程序:

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);
  }
}

我尝试从 user.signup() 删除 share() ,并返回 Observable<any> ,但这没有用 .

6 回答

  • 0

    我确实遇到了这个问题,在我的情况下 responseType 假设是 text (因为设计的API endpoints )而不是默认的 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' });
    }
    

    我认为这个错误消息太笼统了,如果它的开发人员可以提供更多细节/有用的错误消息,那就太好了 . 谢谢 .

  • 1

    碰巧我在 Watch 模式下进行单元测试 . 停止构建,再次触发它=错误消失 .

  • 0

    在使用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 section advices,并在HTTP POST调用上添加带有catchError运算符的Observable管道时,您可以获得正确的HTTP错误详细信息 . 在这种情况下,它不会转到 rxjs/util/subscribeToResult.js:71TS source #L80TypeError: You provided 'undefined' where a stream was expected 默认错误情况,而是转到 rx/util/subscribeToResult.js:23TS 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

  • 0

    就我而言,错误是由不同的问题引起的 .

    我在两个不同的方面提供服务 . 我曾写过:

    @Injectable({provideIn: 'root'})
    

    我也在 app.module.ts 提供模块 . 因此,如果您遇到此错误,可以在继续之前进行检查

  • 0

    在我的情况下,我回来了空回来:

    if (...)
       return; // problem here
    

    为了修复,我返回了观察对象:

    if (...)
       return req.next();
    
  • 12

    这里解决了正确的方法:)

    尝试使用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});
      }
    

相关问题