2017-06-29 199 views
5

在Angular2中,根據第一個API調用的結果實現第二個API調用的正確方法是什麼?我的一個Angular2組件有以下方法。我嘗試了在另一個訂閱完成訂閱,而第二個訂閱的響應總是'未定義'。Angular2在訂閱內訂閱

根據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

您將需要使用.flatMap()如果你想鏈中的ObservablesflatMap().then()相同如果您正在考慮Promise的方式。

而是執行此操作:

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,我必須進行第二個API調用。 – Rama

+0

@Rama Yeap,我的壞。見編輯 – CozyAzure

+0

不幸的是,這並沒有奏效。 processedSearchResult.groupId仍未定義。 – Rama