私はAngular2でプロジェクトを開始していますが、開発者はPromiseではなくRXJS Observableを推奨しているようです。
サーバーから要素のリスト(エピックス)を取得することに成功しました。しかし、たとえばidを使用して要素をフィルタリングするにはどうすればよいですか?
次のコードは私のアプリからの抜粋であり、最終的な作業ソリューションを示しています。それが誰かを助けることを望みましょう。
@Injectable()
export class EpicService {
private url = CONFIG.SERVER + '/app/'; // URL to web API
constructor(private http:Http) {}
private extractData(res:Response) {
let body = res.json();
return body;
}
getEpics():Observable<Epic[]> {
return this.http.get(this.url + "getEpics")
.map(this.extractData)
.catch(this.handleError);
}
getEpic(id:string): Observable<Epic> {
return this.getEpics()
.map(epics => epics.filter(epic => epic.id === id)[0]);
}
}
export class EpicComponent {
errorMessage:string;
epics:Epic[];
epic:Epic;
constructor(
private requirementService:EpicService) {
}
getEpics() {
this.requirementService.getEpics()
.subscribe(
epics => this.epics = epics,
error => this.errorMessage = <any>error);
}
// actually this should be eventually in another component
getEpic(id:string) {
this.requirementService.getEpic(id)
.subscribe(
epic => this.epic = epic,
error => this.errorMessage = <any>error);
}
}
export class Epic {
id: string;
name: string;
}
よろしくお願いします。
実際の配列をフィルタリングし、その周囲にあるオブザーバブルをフィルタリングする必要があります。したがって、Observableのコンテンツ(Epic[]
)をフィルター処理されたEpic
にマップします。
getEpic(id: string): Observable<Epic> {
return this.getEpics()
.map(epics => epics.filter(epic => epic.id === id)[0]);
}
その後、subscribe
からgetEpic
に変更し、必要な操作を実行できます。
これを行うには、flatMap
のJS配列フィルターメソッドの代わりに、filter
のObservable
およびmap
メソッドを使用します。何かのようなもの:
this.getEpics()
.flatMap((data) => data.epics) // [{id: 1}, {id: 4}, {id: 3}, ..., {id: N}]
.filter((epic) => epic.id === id) // checks {id: 1}, then {id: 2}, etc
.subscribe((result) => ...); // do something epic!!!
flatMap
は、フィルタリングのための特異なインデックスを提供します。次に、結果で次に何が起こるかを把握できます。
Angularのドキュメントに従って、フィルター内の==
の使用に関係なく文字列と数値を比較できないことを示すTypeScriptがエラーをスローする場合、フィルター内の+
の前にepic.id
を追加します。
.flatMap(...)
.filter((epic) => +epic.id === id) // checks {id: 1}, then {id: 2}, etc
.subscribe(...)
例:
https://stackblitz.com/edit/angular-9ehje5?file=src%2Fapp%2Fapp.component.ts
修正を含む元の回答:Observables
は遅延しています。 subscribe
を呼び出して、observable
にリクエストを送信するように指示する必要があります。
getEpic(id:number) {
return this.getEpics()
.filter(epic => epic.id === id)
.subscribe(x=>...);
}
Rxjs 6への更新:
import {filter} from 'rxjs/operators';
getEpic(id:number) {
return this.getEpics()
.pipe(filter(epic => epic.id === id))
.subscribe(x=>...);
}
JavaScriptではhttp呼び出しは非同期であるため、データを取得するにはObservable
sをサブスクライブする必要があります。
getEpic(id: number, callback: (epic: Epic) => void) {
this.getEpics().subscribe(
epics: Array<Epic> => {
let epic: Epic = epics.filter(epic => epic.id === id)[0];
callback(epic);
}
);
}
このメソッドを次のように呼び出すことができます:
this.someService.getEpic(epicId, (epic: Epic) => {
// do something with it
});