Angular/TypeScriptで2つのHTTP get検索をマージしようとしていますが、動作させるのに問題があります。Angular Heroesチュートリアルで2つの検索をマージするには?
Observableを使って英雄を "name"値(https://angular.io/tutorial/toh-pt6#add-the-ability-to-search-by-name)で検索する、Angular 2/4 Tour of Heroesチュートリアルを使って状況を示しています。次のようにヒーロー・search.service.tsのコードは次のとおりです。
import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import { Hero } from './hero';
@Injectable()
export class HeroSearchService {
constructor(private http: Http) {}
search(term: string): Observable<Hero[]> {
return this.http
.get(`api/heroes/?name=${term}`)
.map(response => response.json().data as Hero[]);
}
}
私はヒーロークラスに「同義語」の2番目の文字列値を追加するのと同等の操作を行う必要があります
export class Hero {
id: number;
name: string;
synonym: string;
}
と各ヒーローに同義語を追加します。
import { InMemoryDbService } from 'angular-in-memory-web-api';
export class InMemoryDataService implements InMemoryDbService {
createDb() {
const heroes = [
{ id: 0, name: 'Zero', synonym: 'little' },
{ id: 11, name: 'Mr. Nice', synonym: 'pleasant' },
{ id: 12, name: 'Narco', synonym: 'sleep' },
{ id: 13, name: 'Bombasto', synonym: 'loud' },
{ id: 14, name: 'Celeritas', synonym: 'vegetable' },
{ id: 15, name: 'Magneta', synonym: 'color' },
{ id: 16, name: 'RubberMan', synonym: 'hose' },
{ id: 17, name: 'Dynama', synonym: 'motor' },
{ id: 18, name: 'Dr IQ', synonym: 'smart' },
{ id: 19, name: 'Magma', synonym: 'volcanic' },
{ id: 20, name: 'Tornado', synonym: 'wind' }
];
return {heroes};
}
}
私は、代入することにより同義語でヒーロー・search.service.tsで検索することができます。
.get(`api/heroes/?synonym=${term}`)
私の質問は、名前とシノニムの両方を検索し、名前またはシノニムのどちらかで一致を返す方法です。
ReactiveXのドキュメントからは、答えがマージ演算子:http://reactivex.io/documentation/operators/merge.htmlを使用するように思われます。しかし、私はこれを動作させるのに問題があります。
import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/merge';
import { Hero } from './hero';
@Injectable()
export class HeroSearchService {
constructor(private http: Http) {}
search(term: string): Observable<Hero[]> {
const nameResults = this.http.get(`api/heroes/?name=${term}`);
const synonymResults = this.http.get(`api/heroes/?synonym=${term}`);
nameResults.merge(synonymResults);
return nameResults.map(response => response.json().data as Hero[]);
}
}
ないワーキング・適切にコードがhttps://plnkr.co/edit/4mrL5ReQCSvuzOODixJU?p=previewである:私は上記の英雄search.service.tsコードの次の新しいバージョンを含む、マージ使用してのさまざまな方法を試してみました。
マージが成功したというエビデンスは表示されず、nameResultsはシノニムではなく名前のみを指定します。エラーメッセージは表示されません。
http://reactivex.io/documentation/operators/merge.htmlでRxJSコードは、フォーム
const mergedResults = Rx.Observable.merge(nameResults, synonymResults);
のコードを使用していますが、私はそのようなコードを試してみたときに、私はエラーを取得するには、フラグを立て:
を名前を見つけることができませんは 'Rxの'
私の質問は以下の通りです:
どのようにRxJSマージここに?
もっと適切なRxJSを使用して他のアプローチがありますか?
Hero配列の各行にnamePlusSynonymを追加することなくnamePlusSynonymを計算するなど、Heroクラスのレベルで他のアプローチがありますか?
追加:ここに示唆したコードとhttp://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-mergeにコードを記入しました。コンソール出力を備えた新しいバージョンのhero-search.service.tsを作成しました。
import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/merge';
import { Hero } from './hero';
@Injectable()
export class HeroSearchService {
constructor(private http: Http) {}
search(term: string): Observable<Hero[]> {
const nameResults = this.http.get(`api/heroes/?name=${term}`);
nameResults.subscribe(nameData => console.log('nameData', nameData));
const synonymResults = this.http.get(`api/heroes/?synonym=${term}`);
synonymResults.subscribe(synonymData => console.log('synonymData', synonymData));
const combinedResults = nameResults.merge(synonymResults);
combinedResults.subscribe(combinedData => console.log('combinedData', combinedData));
return combinedResults.map(response => response.json().data as Hero[]);
}
}
ただし、nameResultsではなくsynonymResultsのみが表示されます。 nameResultsとsynonymResultsはどちらもコンソールの出力でOKですが、combineResultsはデータとシノニム結果のURLのみを持ち、マージメソッドの影響を受けていないようです。
私も同様の結果を得て、連結で試しました。
それは私が右の段階で組み合わせることが、異なる段階で組み合わせることと同じ結果が得られる、唯一の同義語を示すないよようだ:
search(term: string): Observable<Hero[]> {
const nameResults = this.http.get(`api/heroes/?name=${term}`).map(response => response.json().data as Hero[]);
nameResults.subscribe(nameData => console.log('nameData', nameData));
const synonymResults = this.http.get(`api/heroes/?synonym=${term}`).map(response => response.json().data as Hero[]);
synonymResults.subscribe(synonymData => console.log('synonymData', synonymData));
const combinedResults = nameResults.merge(synonymResults);
combinedResults.subscribe(combinedData => console.log('combinedData', combinedData));
return combinedResults;
}
2つのHTTPリクエストを使用してクライアント側でマージするのは少し珍しいようです。通常、私は 'api/heroes?synonym = $ {synonym}&name = $ {name}'のようなものを見たいと思うでしょう。しかし、あなたが欠けているものは、 'nameResults = nameResults.merge(synonymResults);'あなたがマージしたオブザーバブルであるmergeからのリターンを無視していることです。 – Pace
また、 'let combinedResults = nameResults.merge(synonymResults)'を呼び出し、 'combinedResults.map(...) 'を返します。 – Pace
最後の2行を' const combinedResults = nameResults'に変更します。マージ(synonymResults); return combinedResults.map(response => response.json()。data Hero []); '結果は同義語ではあるが名前ではない。 –