質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Angular

Angularは、JavaScriptフレームワークです。AngularJSの後継であり、TypeScriptベースで実装されています。機能ごとに実装を分けやすく、コードの見通しが良いコンポーネント指向です。

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

Q&A

解決済

2回答

5122閲覧

[Angular(Typescript)]subscribeで取得したデータを用いてif文で条件分岐し、値を返す関数を作りたい

aoa02ssm

総合スコア1

Angular

Angularは、JavaScriptフレームワークです。AngularJSの後継であり、TypeScriptベースで実装されています。機能ごとに実装を分けやすく、コードの見通しが良いコンポーネント指向です。

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

0グッド

0クリップ

投稿2021/07/27 01:43

編集2021/07/28 01:05

実現したいこと

下記のようなコードを書いています。
関数checkTEST内で、

  1. subscribeで取得したデータを用いて(testData = res.body)
  2. if文で条件分岐し(if (testData))、値を返したい

のですが、subscribeで取得する前にif文が始まってしまいます(testDataがundefined)。
今の状態では同期処理ができていないのだと思うのですが、良いやり方はありますでしょうか。

該当のソースコード

typescript

1export class TestComponent implements OnInit { 2 3 load(){ 4 5 if(this.checkTEST(testID,testCount)){ 6 // 略 7 } 8 9 } 10 11 checkTEST(testID: number, testCount: number){ 12 let testData; 13 this.testService.countTest(testID).subscribe(res => { 14 // 1. subscribeで取得したデータを用いて(testData = res.body) 15 testData = res.body; 16 }); 17 18 // 2. if文で条件分岐し(if (testData))、値を返したい 19 if (testData) { 20 return Number(testData) < testCount; 21 } else { 22 return false; 23 } 24 } 25 26}

試したこと

https://teratail.com/questions/129464
上記が近いのではと思い下記のように修正してみましたが、やはり関数内でif文が先に動いてしまうようです。
また、関数checkTESTの戻り値に関して「'void' 型の式は、真実性をテストできません。」というエラーが出ます。

typescript

1export class TestComponent implements OnInit { 2 3 testData: Subject<number> = new Subject(); 4 5 load(){ 6 7 if(this.checkTEST(testID,testCount)){ 8 // 略 9 } 10 11 } 12 13 checkTEST(testID: number, testCount: number) { 14 this.counter(testID).subscribe(testData => { 15 if (testData) { 16 return Number(testData) > testCount; 17 } else { 18 return false; 19 } 20 }); 21 } 22 counter(testID: number){ 23 let testData; 24 this.testService.countTest(orgId).subscribe(res => { 25 testData = res.body; 26 this.testData.next(testData); 27 }); 28 return this.testData; 29 } 30 31}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

subscribeの引数はコールバック関数になっていますので、subscribeの中でreturnしても、checkTEST関数の返値にはなりません。

ですから、

typescript

1checkTEST(testID: number, testCount: number) { 2 this.counter(testID).subscribe(testData => { 3 if (testData) { 4 return Number(testData) > testCount; 5 } else { 6 return false; 7 } 8 }); 9}

この関数は実際には何も値を返さない関数になっており、IF文の判定に必要なbooleanを返さないので、'void' 型の式は、真実性をテストできません。のようにエラーが出るものと思われます。

さて、お察しの通り、subscribeは非同期的に実行される関数です。「同期っぽく」実行することはできますが、完全に同期的に実行することはできないので、以下のようなコードになるかと思います。

typescript

1export class TestComponent implements OnInit { 2 3 load(): void { 4 5 this.checkTEST(testID,testCount).subscribe((bool) => { 6 if(bool) { 7 // 何かしらの処理 8 } 9 }) 10 11 } 12 13 // または 14 15 async load(): Promise<void> { 16 17 const bool = await this.checkTEST(testID,testCount).toPromise() <-- RxJS v6までの記法です 18 19 if(bool) { 20 // 何かしらの処理 21 } 22 23 } 24 25 checkTEST(testID: number, testCount: number): Observable<boolean> { 26 return this.testService.countTest(testID).pipe( 27 map((res) => { 28 if (res.body) { 29 return Number(res.body) < testCount; 30 } else { 31 return false; 32 } 33 }) 34 ); 35 } 36}

投稿2021/08/04 07:37

kaito3desuyo

総合スコア143

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

aoa02ssm

2021/10/19 02:49

遅くなり申し訳ございません、ご回答ありがとうございました! kaito3desuyo様の「 // または」から下のasync/awaitを使用した方法が自分には分かりやすく、無事実装できました。
guest

0

subscribeメソッドはSubjectにデータが発生した際のコールバック関数を定義しているので、そのまますり抜ける動作は正しいです。this.testService.countTest(testID)がSubjectなのか確認できませんが。
Subject.next()が呼ばれることによりコールバック関数が実行されます。

ヒント程度の内容ですが、ご容赦下さい。

rxjs Subjectの自前のサンプルです。用法が異なるようですが、ご参考になりましたら。

投稿2021/07/28 11:59

BlueMoon

総合スコア1339

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問