Rail5バックエンドでAngular7を使用しています。Rails5バックエンドとやり取りするために使用するサービスがあります...
import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
@Injectable()
export class CurrencyService {
constructor(private _http: HttpClient) { }
index() {
let ret = this._http.get<Object[]>('api/currencies').map(r => r);
console.log(ret);
return ret;
}
refresh() {
return this._http.get<Object[]>('api/refresh').map(r => r);
}
}
これは、サービスと対話するsrc / app /app.component.tsファイルにあります...
import { CurrencyService } from './../shared/currency.service';
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
currencies = [];
title = 'app';
apiStatus: string;
constructor(private _currencySrv: CurrencyService) { }
ngOnInit() {
this._currencySrv.index<Object[]>().subscribe(
currencies => this.currencies = currencies);
}
refresh() {
this._currencySrv.refresh<Object[]>().subscribe(
currencies => this.currencies = currencies);
}
}
返されたObservableオブジェクトから「index」と「refresh」の呼び出しの結果を抽出するにはどうすればよいですか?ngForを使用して「currencies」メンバー変数を反復処理しようとすると、エラーが発生します
ERROR TypeError: Cannot read property 'name' of undefined
at Object.eval [as updateRenderer] (AppComponent.html:4)
at Object.debugUpdateRenderer [as updateRenderer] (core.js:14735)
at checkAndUpdateView (core.js:13849)
at callViewAction (core.js:14195)
at execComponentViewsAction (core.js:14127)
at checkAndUpdateView (core.js:13850)
at callWithDebugContext (core.js:15098)
at Object.debugCheckAndUpdateView [as checkAndUpdateView] (core.js:14635)
at ViewRef_.detectChanges (core.js:11619)
at eval (core.js:5918)
結果は「data」というフィールドにラップされていると思いますが、「ngserve」を使用してAngularサーバーを起動しようとすると、あらゆる種類のコンパイルエラーなしでフィールドを抽出する適切な方法がわかりません。
編集: src / app /app.component.htmlにあります
<!--The content below is only a placeholder and can be replaced.-->
<ul>
<ng-container *ngIf="currencies?.length">
<li *ngFor="let currency of currencies">
<div>{{currency.name}}</div>
<div>{{currency.country}}</div>
<div>{{currency.rate / 100}}</div>
</li>
</ng-container>
</ul>
更新
それでも、データは表示されません。
コードで修正する必要のある問題はたくさんあります。@JBNizetはすでにほとんどの問題について言及しているようです。
まずはサービスから始めましょう。
rxjs6
Angularアプリケーションで使用している場合は、使用したrxjs6
構文の代わりにパイプ可能な演算子の構文を使用できますrxjs5
。(出典:docs)import
のための場所をObservable
するrxjs
とmap
しますrxjs/operators
。(出典:docs)import { Http } from '@angular/http';
冗長です。このパッケージは非推奨です。@angular/common/http
代わりに使用してください。(出典:docs)Object
非プリミティブボックス化オブジェクトを指すため、使用しないでください。(出典:docs)。代わりに、any
またはさらに良い方法として、バックエンド応答を定義するインターフェースを作成してください。map
現在の書き方では、何もしません。代わりに、バックエンドがオブジェクトを返すdata
ので、を使用しmap
てdata
。だけを返すことができます。refresh
APIが何をするのかはわかりませんが、currencies
APIと同じデータを取得するだけの場合は、不要のようです。他のデータが含まれているかどうかわからないので、答えはそのままにしておきます。このすべてを念頭に置いて、あなたCurrencyService
は今のようになります
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { CurrenciesResponse, Currency } from 'path/to/your/interface';
@Injectable()
export class CurrencyService {
constructor(
private _http: HttpClient
) { }
index(): Observable<Currency[]> {
return this._http.get<CurrenciesResponse>('api/currencies').pipe(
map((res: CurrenciesResponse) => res.data)
);
}
refresh(): Observable<Currency[]> {
return this._http.get<CurrenciesResponse>('api/refresh').pipe(
map((res: CurrenciesResponse) => res.data)
);
}
}
インターフェイスは次のようになります
export interface CurrenciesResponse {
data: Currency[];
// Add other backend response properties here if present
}
export interface Currency {
name: string;
country: string;
rate: number;
// ...
}
インターフェイスを別のファイルに追加し、必要に応じてインポートします。
コンポーネントには、問題が1つしかないようです。あなたが起動したときに型引数を指定する必要はありませんindex()
とrefresh()
からcurrencyService
、彼らは一般的な方法ではないからです。IDEは通常、次のようなエラーでこれについて警告する必要がありますExpected 0 type arguments, but got 1
currencies: Currency[] = [];
title: string = 'app';
apiStatus: string;
constructor(
private _currencySrv: CurrencyService
) { }
ngOnInit() {
this._currencySrv.index().subscribe(currencies => {
this.currencies = currencies;
});
}
refresh() {
this._currencySrv.refresh().subscribe(currencies => {
this.currencies = currencies;
});
}
最後に、HTMLでは、データが含まれていない限り何も印刷されないため、ngIf
は冗長です。ngFor
currencies
<ul *ngFor="let currency of currencies">
<li>
<div>{{currency.name}}</div>
<div>{{currency.country}}</div>
<div>{{currency.rate / 100}}</div>
</li>
</ul>
StackBlitzの実際の例を次に示します。angular-in-memory-web-api
API応答に使用しました。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加