In Angular2, what would be the correct way to implement a second API call based on the result from the first API call? One of my Angular2 components has the following method. I tried with having a subscribe inside another subscribe on complete and the response from the second subscribe is always 'undefined'.
Edit based on suggestion 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'));
}
You will need to use
.flatMap()
if you want to chain yourObservables
.flatMap()
is the same as.then()
if you are thinking of thePromise
way.Do this instead:
Edit:
You can do any interventions inside your
flatMap()
callbacks. You can check if thegroupId
exist or not, only then you proceed to your next call. If it doesn't, simply returns an empty Observable usingObersvable.empty()
.