Reputation: 385
I have a code that calls a function as shown below:
this.getAllOptions(questionID);
console.log("++++++++++++++++++++++++++++++++");
console.log(this.result);
the function is very simple, it calls a service that returns an array of object. From the returned data, I only need the "item.Content" in a string format, as shown below.
result: string;
getAllOptions(question_ID){
this.result = "";
this._service.getOptionsQuestion(question_ID)
.subscribe( data => {
data.forEach(item => {
console.log(item.Content);
this.result += item.Content;
});
});
}
But the problem is, the codes after calling the function "getAllOptions()" get executed first. I want the codes after calling the methods to wait until function done executing.
Is that possible?
Upvotes: 5
Views: 31797
Reputation: 31
We can also address the issue by returning a promise from the getAllOptions function.
result: string;
getAllOptions(question_ID): Promise<void>{
let resolveRef;
let rejectRef;
//create a new promise. Save the resolve and reject reference
let dataPromise: Promise<void> = new Promise((resolve, reject) => {
resolveRef = resolve;
rejectRef = reject;
});
this.result = "";
this._service.getOptionsQuestion(question_ID)
.subscribe( (data: any) => {
data.forEach(item => {
console.log(item.Content);
this.result += item.Content;
});
// resolve the promise once result is populated
resolveRef(null);
});
//return promise created.
return dataPromise;
}
// execute the console logs on then part of the promise returned by getAllOptions
this.getAllOptions(questionID).then( () => {
console.log("++++++++++++++++++++++++++++++++");
console.log(this.result);
});
Upvotes: 2
Reputation: 249746
You need to wait for the data to arrive. Immediately after the call to getOptionsQuestion
completes the observable created in getOptionsQuestion
has not yet received any data so the callback you passed to subscribe
has not been called yet.
There are several approaches to wait for the data, personally I prefer the async/await syntax in Typescript, makes for more readable code:
import 'rxjs/add/operator/toPromise';
import 'rxjs/add/operator/map';
import * as rsx from 'rxjs'
class Test {
// Dummy service decalration
_service : {
getOptionsQuestion(nr: number): rsx.Observable<Array<{Content : string }>>
}
result: string;
async getAllOptions(question_ID: number){
this.result = "";
const data = await this._service.getOptionsQuestion(question_ID).toPromise()
data.forEach(item => {
console.log(item.Content);
this.result += item.Content;
});
}
async otherMethod (questionID : number){
await this.getAllOptions(questionID);
console.log("++++++++++++++++++++++++++++++++");
console.log(this.result);
}
}
Upvotes: 3