環境
- Angular 9.1.11
- rxjs 6.5.5
- Azure Functions (.NET Core 3.1、データ要求先として)
準備
Azure Functionsで1つ関数を用意する。
まずはデータ用クラスを用意して、
class NumberValue { public int Value { get; set; } }
そのデータ用クラスの配列をJSON形式で返す関数を用意する。
[FunctionName("GetNumbers")] public static async Task<IActionResult> GetNumbers( [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req, ILogger log) { var result = new List<NumberValue>(); await Task.Run(() => { for (var i = 0; i < 10; i++) { result.Add(new NumberValue() { Value = i }); } }); return new OkObjectResult(JsonConvert.SerializeObject(result)); }
Serviceの実装
では、そのデータを要求して受け取る処理を作る。
Azure Functionsと同じ型をinterfaceで用意する。
export class NumberValue { Value: number; }
ServiceにGetNumbersを呼び出してObservableを返すメソッドを作成する。
import { NumberValue } from './data-types/number-value'; import { HttpClient, HttpHeaders } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { Observable, Subject } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class SampleService { constructor(private http: HttpClient) { } /** * NumberValueの配列を返す。 */ public getNumbers(): Observable<Array<NumberValue>> { let result: Subject<Array<NumberValue>> = new Subject<Array<NumberValue>>(); this.http.get('https://yoursitename.azurewebsites.net/api/GetNumbers') .subscribe(response => { result.next(response as Array<NumberValue>); // forkJoinなどで待ち受ける場合はcomplete()を呼び出す必要がある。 result.complete(); }); return result; } }
参考にしたのはこちら。
- Angular 日本語ドキュメンテーション - サーバーからデータの取得
- RxJS - Angular6 RxJsのsubscribeのデータをreturnで返したい|teratail
- RxJS - forkJoin
HttpClient.getでObservable<any>
が返ってくるので、編集してからメソッドの戻り値に使いたい場合はSubjectに詰め込んで返してあげると良い。
forkJoinのDescriptionには「complete()を待つ」と書いてあるので、戻り値として使うSubjectのcomplete()を呼び出しておけば、forkJoinで使ってもすり抜ける事が無くなる。
(HttpClient.getの戻り値を編集しない場合はSubjectを書く必要が無く、return this.http.get('https://yoursitename.azurewebsites.net/api/GetNumbers') as Observable<Array<NumberValue>>;
で大丈夫。)
使ってみる
実装したServiceをComponentで呼び出してみる。
import { SampleService } from './../sample.service'; import { Component, OnInit } from '@angular/core'; import { forkJoin } from 'rxjs'; @Component({ selector: 'app-sample', templateUrl: './sample.component.html', styleUrls: ['./sample.component.css'] }) export class SampleComponent implements OnInit { responseData: string = ''; constructor(private sampleService: SampleService) { } ngOnInit(): void { } public onHttpGet() { this.responseData = ''; // forkJoinで2回呼び出して、 forkJoin( this.sampleService.getNumbers(), this.sampleService.getNumbers() ) .subscribe(response => { // subscribeでまとめて受ける。 this.responseData = JSON.stringify(response); }); } }
メソッドを呼び出して、Azure Functionsのアクセス結果が2回分出ていることを確認できた。