2017-06-29 12 views
5

Angular2では、最初のAPI呼び出しの結果に基づいて2番目のAPI呼び出しを実装する正しい方法は何でしょうか?私のAngular2コンポーネントの1つに、次のメソッドがあります。私は完全に別のサブスクリプションの中にサブスクリプションを持っているとしようとし、2番目のサブスクリプションからの応答は常に '未定義'です。Angular2 subscribe inside subscribe

CozyAzureからの提案に基づいて編集します。次のように

export interface Result { 
    host: string; 
    resourceUri: string; 
    groupId?: string; 
    resource?: any; 
} 

private curateResults(searchTerm: string, searchResults: SearchResults): Result[] { 
    const results: Result[] = []; 
    if (searchResults.results !== undefined && searchResults.results.length > 0) { 
     searchResults.results.forEach((result: any) => { 
     const processedSearchResult: Result = { 
      host: result.origin.toString(), 
      resourceUri: result.url.toString() 
     }; 
     processedSearchResult.resource = undefined; 
     processedSearchResult.groupId = undefined; 
     this.bopsHttpService.getResourceData(processedSearchResult.host, processedSearchResult.resourceUri) 
      .flatMap((resource: any) => { 
      processedSearchResult.groupId = this.getGroupIdFromResource(resource, 'groupId'); 
      if (processedSearchResult.groupId === undefined) { 
       const uriParts = processedSearchResult.resourceUri.split('/'); 
       const predicate = uriParts[uriParts.length - 2]; 
       if (predicate === 'group') { 
       processedSearchResult.groupId = uriParts[uriParts.length - 1]; 
       return Observable.empty(); 
       } else { 
       return this.bopsHttpService.getGroupRelation(processedSearchResult.resourceUri.split('/').pop()); 
       } 
      } else { 
       return Observable.empty(); 
      } 
      }) 
      .subscribe((relation: any) => { 
      if (relation !== undefined) { 
       processedSearchResult.groupId = relation.objectId; 
       console.log('Fetched Group ID: ', processedSearchResult.groupId); 
      } 
      }); 
     results.push(processedSearchResult); 
     }); 
    } 
    return results; 
} 

私のHTTP呼び出しは以下のとおりです。

public getGroupRelation(subjectId: string): Observable<Relation> { 
    const path = `${this.bopsServiceUrl}/relation/${subjectId}/group`; 
    const queryParameters = new URLSearchParams(); 
    queryParameters.set('at', new Date().toISOString()); 
    const options = new RequestOptions({ 
     headers: this.headers, 
     search: queryParameters 
    }); 
    return this.http.get(path, options) 
     .map((response: Response) => response.json()) 
     .catch((error: any) => Observable.throw(error.json().error 
     || 'BOPS Server error during get group relation Operation', 
      error.json())); 
    } 

    public getResourceData(host: string, resourceUri: string): Observable<any> { 
    const path = host + resourceUri; 
    const queryParameters = new URLSearchParams(); 
    queryParameters.set('at', new Date().toISOString()); 
    const options = new RequestOptions({ 
     headers: this.headers, 
     search: queryParameters 
    }); 
    return this.http.get(path, options) 
     .map((response: Response) => response.json()) 
     .catch((error: any) => Observable.throw(error 
     || 'BOPS Server error during Get Resource Data Operation')); 
    } 
+0

"processedSearchResult.groupId"は、常に定義されていません。 – Rama

答えて

6

あなたが連鎖あなたObservablesする場合は.flatMap()を使用する必要があります。 Promiseの方法を考えている場合は、flatMap().then()と同じです。

代わりにこれを行います。

this.bopsHttpService.getResourceData(processedSearchResult.host, processedSearchResult.resourceUri) 
    .flatMap(() => { 
     //check if groupId exist, or whatever your logic is 
     if(hasGroupId){ 
      //groupId exist, proceed to call your second request 
      return this.bopsHttpService.getGroupRelation(processedSearchResult.resourceUri.split('/').pop()); 
     } 
     //groupId doesn't exist, return an empty Observable. 
     return Observable.empty(); 

    }) 
    .subscribe((relation) => { 
     if (relation !== undefined) { 
      processedSearchResult.groupId = relation.objectId; 
      console.log('Fetched Group ID: ', processedSearchResult.groupId); 
     } 
    }) 

編集:

はあなたがあなたのflatMap()コールバック内の任意の介入を行うことができます。 groupIdが存在するかどうかを確認することができます。その場合にのみ、次の呼び出しに進みます。そうでない場合は、単にObersvable.empty()を使用して空のObservableを返します。

+0

@CozyAzureありがとうございます。私はこれに従うかわからない。最初のAPI呼び出しのリソースにgroupIdがない場合にのみ、2番目のAPI呼び出しを行う必要があります。 – Rama

+0

@Rama Yeap、私の悪い。編集 – CozyAzure

+0

を参照してください残念ながら、それは動作しませんでした。 processedSearchResult.groupIdはまだ定義されていません。 – Rama

関連する問題