I have a situation where I need to run a loop and fetch respective items' description. Then along with the item Ids and other information I have to include the fetched description in a datatable.
addDescription(){
this.arrayOfItems.forEach(element => {
// CALL a function which will make a service call
this.fetchDescription(element);
//CODE TO DECLARE AN INTERFACE TO ASSIGN RESPECTIVE VALUES. eg.
// ITEM_ID : element.id,
// ITEM_DEF : this.fetchedDescription.join("\n")
}
Function body:
fetchDescription(elementToFetchDesc){
//Declaring HTTPPARAMS in PassingParams variable
this.componentService.getDesc(PassingParams)
.subscribe((response: HttpResponse<any>) => {
if(response.status ==200){
this.fetchedDescription = reponse.body.output.slice(6,-1);
}
//Code if response status is NOT 200
}
In componentService
Service:
construcutor(private httpConn: HttpClient){}
getDesc(Params){
// Declare URL
return this.httpConn.get(URL, {params: Params, observe: 'response'});
}
The problem:
As it's running in a loop and the subscription is an async call, so, after running the loop in forEach
it's coming out. As a result the description is not getting assigned to the variable (ITEM_DEF
) in the interface.
To solve this issue I implemented a little change to use promise
.
In service I added:
import 'rxjs/add/operator/toPromise';
And updated the service method as:
return this.httpConn.get(URL, {params: Params, observe: 'response'})
.toPromise(); // converted observable into promise
Also changed in component:
Inside fetchDescription
function:
replaced .subscribe
as .then
But the issue still persists. Please let me know where I'm doing wrong to implement this logic.
the solution is to convert observable to promise but not using then!
Example:
This is your service function that sends the request:
myRequest(num) {
return this.http.get('http://someUrl.com/' + num).toPromise();
}
This is the function to send all requests in a component class:
async sendAll() {
let response = [];
for(let i = 0; i < 5; i++) {
response[i] = await this.myService.myRequest();
}
// Got all the results!
}