web-dev-qa-db-ja.com

TypeError:ストリームが予期される場所に「未定義」を指定しました

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>_を返しましたが、役に立ちません。

11
Matt Raible

Matt Raible 's(OP) se Ionic JHipsterがOIDC認証でモバイルアプリを作成する場合 ブログ記事。ただし、OIDCではなくJWT認証を選択します。

問題の起源は問題の混合でした。

LivereloadサーバーでIonicアプリを実行すると問題が発生しました。CORSの問題が発生し、Angular HTTPがクラシックHTTP failure response for (unknown url): 0 Unknown Errorを返します。0はHTTPエラーコードです。ただし、現在のケースでは、問題はObservableレベルでの誤ったエラー処理によって隠されていました。

AngularのHttpClient #Error Details セクションのアドバイスに従い、HTTP POST呼び出しでcatchError演算子を使用して監視可能なパイプを追加すると、適切なHTTPエラーの詳細を取得できます。この場合、_rxjs/util/subscribeToResult.js:71_( TS source#L8 )_TypeError: You provided 'undefined' where a stream was expected_のデフォルトのエラーケースではなく、_rx/util/subscribeToResult.js:23_( TSソース#L34 )。パイプ処理されたメソッドでエラーが適切に処理されます。

Observable呼び出しを追跡した後、このテンプレート src/providers/auth/auth-interceptor.ts に示されているように、現在のデフォルトの認証インターセプターがHTTPエラー401をキャッチし、他のものに対しては基本的に何もしません。それらをミュートし、それらの伝播を防ぎます。

TL; DRJWTの場合の解決策は、単に_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

17

私はこの問題に直面しました。私の場合、responseTypeはデフォルトのtextではなくjson(設計されたAPIエンドポイントのため)であると想定しています。

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

このエラーメッセージは一般的すぎると思います。開発者がより詳細で役立つエラーメッセージを提供できればいいと思います。ありがとう。

4
Sid Morad

私の場合、私は空のリターンで再帰していました:

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

修正するために、観測されたオブジェクトを返しました。

if (...)
   return req.next();
3
FindOutIslamNow

ここで正しい方法で解決しました:)

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});
  }
2
Badis Merabet

私は同じエラーがあり、典型的なシナリオは、特定の条件に基づいて異なるアクションを返すというものでした。しかし、1つの条件の処理が欠落しており、私の影響下で何も返さなかった。このとき、この問題が発生しました。このようなインスタンスを回避するために、デフォルトの戻りアクションを使用することを常にお勧めします。

...mergeMap((res: FetchWorkflowStatusResponse) => {
   if(this){
      return action1
   } else if(that){
      return action2
   }
}

ここで、thisおよびthat以外の値が来ると、returnステートメントはなくなり、エラーがスローされます。

1
amit

私の場合、NgRxエフェクトでアクションを返すのを怠っていました。 1つの条件に対してのみアクションを返す条件ステートメントがありました。

0
Zachary Bennett

私の場合、エラーは別の問題が原因で発生しました。

私は2つの異なる点でサービスを提供していました。私は書いた:

@Injectable({provideIn: 'root'})

また、app.module.ts。このエラーが発生した場合は、先に進む前にこれを確認できます

0

私の場合、エラーは別の問題が原因で発生しました。

私は2つの異なる点でサービスを提供していました。私は書いた:

@Injectable({provideIn: 'root'})そしてapp.module.tsでもモジュールを提供していました。このエラーが発生した場合は、先に進む前にこれを確認できます

0
Cáptáin Mosa

時計モードでユニットテストをしているときに偶然に起こりました。ビルドを停止し、再度トリガーします=エラーはなくなりました。

0
Leo Lanese

ngrxAngularを使用してトークンを格納していました。私の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>>;
                    }
                })
            );

    }
0
Jalal El-Shaer