Angular2 subscribe inside subscribe

In Angular2, what would be the right way to implement a second API call based on the result of the first API call? One of my Angular2 components has the following method. I tried with a subscription inside another termination subscription, and the response from the second subscription is always "undefined".

Change based on offers from 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; } 

My http calls are as follows:

  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')); } 
+5
source share
1 answer

You will need to use .flatMap() if you want to link your Observables . flatMap() same as .then() if you are thinking of a Promise path.

Do this instead:

 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); } }) 

Edit:

You can do any kind of intervention inside your flatMap() . You can check if groupId or not, only after that you proceed to the next call. If this is not the case, simply returns an empty Observable using Obersvable.empty() .

+6
source

Source: https://habr.com/ru/post/1269341/


All Articles