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

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

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

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

Q&A

1回答

592閲覧

AngularでのAPIの呼ぶタイミング、方法(MEANスタック)

untan.r

総合スコア17

Angular

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

0グッド

0クリップ

投稿2018/08/30 15:06

MEANスタックにてWebサービスを開発しています。
MongoDB, Express, Nodeを用いてデータベース上からデータを取得するAPIを作成しました。
これを用いて、Angularでページを作成したいのですが、APIを呼ぶタイミングや方法で困っています。

仮に以下のようなAPIがあるとします。

APIの仕様(例)

GET /api/list1

response

1{ 2 success: true, 3 data: ['AAA', 'BBB', 'CCC', 'DDD', 'EEE'] 4}

GET /api/list2

response

1{ 2 success: true, 3 data: ['あああ', 'いいい', 'ううう', 'えええ', 'おおお'] 4}

###完成イメージ
イメージ説明

これを行うために以下のようなコードを書きました。

Angularのコード

api.service.ts

typescript

1import { HttpClient} from '@angular/common/http'; 2import { Observable } from 'rxjs/Observable'; 3 4export class ApiService { 5 constructor(private http: HttpClient) {} 6 get_list1() { 7 return this.http.get('/api/list1').catch(error => { 8 // 9 return Observable.throw(error); 10 }).sharedReplay(); 11 } 12 get_list2() { 13 return this.http.get('/api/list2').catch(error => { 14 // 15 return Observable.throw(error); 16 }).sharedReplay(); 17 } 18}

app.component.html

html

1<select id="list1"> 2 <option *ngFor="let item of list1" ![イメージ説明](051dedbbc6d82d0a26a8ec265eecb428.png)"{{item}}">{{item}}</option> 3</select> 4<select id="list2"> 5 <option *ngFor="let item of list2" value="{{item}}">{{item}}</option> 6</select>

app.component.ts

typescript

1import { Component } from '@angular/core'; 2import { ApiService } from './services/api.service'; 3 4@Component({ 5 selector: 'app-root', 6 templateUrl: './app.component.html', 7 styleUrls: ['./app.component.css'] 8}) 9export class AppComponent { 10 list1: string[]; 11 list2: string[]; 12 constructor(private apiService: ApiService) {} 13 ngOnInit() { 14 this.apiSerivce.getList1().subscribe((res :{success: true, data: string[]}) => { 15 if(data.success) { 16 this.list1 = res.data; 17 }else { 18 console.log('get list1 error'); 19 } 20 }); 21 this.apiSerivce.getList2().subscribe((res :{success: true, data: string[]}) => { 22 if(data.success) { 23 this.list2 = res.data; 24 }else { 25 console.log('get list2 error'); 26 } 27 }); 28 } 29}

APIを呼ぶタイミング(ngOnInitで呼んでも構わないのかどうか)と、
このように、並列?にAPIを呼ぶ方法があまり良いとは思えないので、
複数のAPIを呼ぶ際はどのようにすればよいか、ご教授ください。
よろしくお願いいたします。

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

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

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

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

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

guest

回答1

0

いろんな意見があると思うので、あくまで参考程度に

APIを呼ぶタイミング(ngOnInitで呼んでも構わないのかどうか)と、

初期処理ならngOnInitで間違ってないと。なのかをトリガーとしてデータを取得するなら、そのイベント発生時(clickイベントなど)にデータを取得するようにします。

このように、並列?にAPIを呼ぶ方法があまり良いとは思えないので

"並列"ではなく非同期ですね。サーバーサイドレンダリングではないので「しょうがない」ではなく「SPAの仕様」と考えます

ただし今のコードのままだと大量のデータを取得した場合に画面に違和感を覚えるかもしれません

  • ブラウザ画面の作成・表示がされる。
  • その後、データの取得完了→ブラウザ画面に反映
  • 画面(この場合セレクトボックス)がプリっとなるかも(表現しにくい)

私はこういう現象を避ける手としてプログレスダイアログなどを利用しています。

投稿2018/09/02 13:11

mosapride

総合スコア1480

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

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

untan.r

2018/09/03 03:46

回答ありがとうございます。 すみません質問の書き方が悪かったのですが、 非同期処理に違和感を感じているのではなく、 2つのAPIを呼ぶ際の、方法に関してなのです。 このような方法で問題ないのでしょうか? よろしくお願い致します。
mosapride

2018/09/03 06:29

今の状態は疎結合なのでシンプルで好きです(好みの問題もあるので"良い"とは明言できないです) list1とlist2のデータを同時に取得するようにAPIサーバの処理を追加することにより複数の非同期通信を回避することはできるでしょうけど、リクエスト側(Angular)の初期処理の仕様を変更するとAPIサーバの変更も変更しないといけなく、密結合な状態になります。 Angular側の仕事を軽くしてAPIサーバの方で処理した方が楽な場合もあると思いますけどケースバイケースですね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問