TypeError:您提供了“未定义"的预期流 [英] TypeError: You provided 'undefined' where a stream was expected

查看:164
本文介绍了TypeError:您提供了“未定义"的预期流的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have an Ionic app that has a user provider with a signup() method:

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

由于某种原因,此代码从不调用成功回调,而仅调用错误处理程序.如果这样做,则会导致您在上面的注释中看到错误.

For some reason, this code never calls the success callback, only the error handler. When it does, it results in the error you see in the comment above.

我的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>,但这无济于事.

I tried removing share() from user.signup(), and returning Observable<any>, but that doesn't help.

推荐答案

在使用generator-jhipster-ionic(yo jhipster-ionic提供v3.1.2)创建新项目时,我在

I faced this issue when creating a new project using generator-jhipster-ionic (yo jhipster-ionic giving v3.1.2), following Matt Raible's (OP) Use Ionic for JHipster to Create Mobile Apps with OIDC Authentication blog article, but choosing JWT authentication instead of OIDC.

问题的根源是各种各样的问题.

The origin of the issue was a mix of problems.

使用livereload服务器运行Ionic应用程序时出现问题,发生了CORS问题,Angular HTTP返回了经典的HTTP failure response for (unknown url): 0 Unknown Error,其中0是HTTP错误代码. 但是,在当前情况下,该问题被可观察级别的错误处理隐藏了.

I had the issue when running a Ionic app with the livereload server, CORS issues happening and Angular HTTP returning the classic HTTP failure response for (unknown url): 0 Unknown Error, where 0 is the HTTP error code. However, in the current case the issue was hidden by bad error handling at the Observable level.

遵循 Angular的HttpClient #Error详细信息部分的建议,并添加一个在HTTP POST调用上使用catchError运算符的可观察管道,您可以获得正确的HTTP错误详细信息.在这种情况下,而不是转到rxjs/util/subscribeToResult.js:71( TS源#L80 )TypeError: You provided 'undefined' where a stream was expected默认错误情况,它转到rx/util/subscribeToResult.js:23(

When you follow Angular's HttpClient #Error Details section advices, and add an Observable pipe with a catchError operator on the HTTP POST call, you can get the proper HTTP error details. In this case, instead of going down to the rxjs/util/subscribeToResult.js:71 (TS source #L80) TypeError: You provided 'undefined' where a stream was expected default error case, it goes to rx/util/subscribeToResult.js:23 (TS source #L34), and the error is handled properly in the piped method.

在遵循Observable调用之后,我发现当前的默认身份验证拦截器(如本模板所示)

After following the Observable calls, I found that the current default authentication interceptor, as seen in this template src/providers/auth/auth-interceptor.ts catches HTTP error 401 and does nothing for the others, basically muting them and preventing their propagation.

TL; DR 在JWT中,解决方案是简单地删除src/providers/auth/auth-interceptor.ts .catch(...)块,从而允许错误传播到login.service.ts及其错误回调中.

TL;DR In the JWT case, the solution is to simply remove the src/providers/auth/auth-interceptor.ts .catch(...) block, allowing error propagation to login.service.ts, and in its this.authServerProvider.login(credentials).subscribe((data) => { ... }, (err) => { ... }) error callback.

我相信对于您的OIDC案例,其注册方法和错误回调,问题和解决方案可能是相同的.

I believe the issue and solution could be the same for your OIDC case, its signup method, and error callback.

甚至更多,因为可以在第一篇评论中提到的入门示例中找到相同的.catch代码:

Even more since the same .catch code can be found in the starter example mentioned in the first post comments: ionic-jhipster-starter - auth-interceptor.ts#L31

这篇关于TypeError:您提供了“未定义"的预期流的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆