Reputation: 61
I have a service call that returns a promise, but when I try to set the return type as promise I'm having trouble using it in the caller function due to the type not being recognized, so it won't compile.
So I have tried using the below method, but I run into a timing issue (code executes before call finishes)
private getSomeData(): DataObjectArray[] {
return this.myService.something().map((response: Response) => {
return response.children;
});
}
public compileData(): DifferentDataArray[] {
// get some stuff from a config, then make service call
let someData = this.getSomeData();
/* If I have a promise returned, someData errors saying not an array type */
for (let oneData of someData){
/* loop through config data + service data making a return object array */
}
return this.dataCollection;
}
Upvotes: 1
Views: 1848
Reputation: 1997
I recommend in Angular you try to keep things as observables. Its nice to be consistent, instead of flipping back and forth between observables and promises.
I'm not super clear if myService.something() returns a promise or an observable. If observable:
private getSomeData(): Observable<<DataObjectArray[]> {
return this.myService.something().pipe(
map(response => response.children)
);
}
if its a promise very similar but:
private getSomeData(): Observable<<DataObjectArray[]> {
return fromPromise(this.myService.something()).pipe(
map(response => response.children)
);
}
Then:
public compileData(): Observable<DifferentDataArray[]> {
// get some stuff from a config, then make service call
return this.getSomeData().pipe(
map(someData => {
/* If I have a promise returned, someData errors saying not an array type */
var dataCollection = [];
for (let oneData of someData){
/* loop through config data + service data making a return object array */
// should dataCollection.push(changedData);
}
return dataCollection;
});
);
}
Finally to consume somewhere else:
this.compileData().subscribe(compiledData => {
// do something with the compiled data
});
Notes: The pipe operator is pretty powerful. It takes an observable, and lets you do some work on it before returning it. In this case, I used the map operator, because you are just changing the shape of the return a little bit. At the end of the chain, you must always subscribe to an observable to get the data back (per the last black in my example)
Upvotes: 2
Reputation: 14863
You can use the new Javascript keywords async
and await
First make getSomeData
async, which also requires it to return a promise:
private async getSomeData(): Promise<DataObjectArray[]> {
return this.myService.something().map((response: Response) => {
return response.children;
});
}
then await the function in compileData
:
let someData = await this.getSomeData();
However, this means that compileData
because it returns a result, has to be async too. This means you need to add the async
keyword and change the type to Promise<DifferentDataArray[]>
.
In case you don't care about your result, you can call a async function without await, so you also don't have to wait for the result and it is handled in the background. If you rely on the result, you have to await it. In this case, other parts of your application can continue! Anyway, if you are designing an async application you have to think about what happens when anyway.
Your full compileData function:
public async compileData(): Promise<DifferentDataArray[]> {
// get some stuff from a config, then make service call
let someData = await this.getSomeData();
/* If I have a promise returned, someData errors saying not an array type */
for (let oneData of someData){
/* loop through config data + service data making a return object array */
}
return this.dataCollection;
}
public compileData(): DifferentDataArray[] {
// get some stuff from a config, then make service call
let someData = this.getSomeData();
/* If I have a promise returned, someData errors saying not an array type */
for (let oneData of someData){
/* loop through config data + service data making a return object array */
}
return this.dataCollection;
}
Upvotes: 1
Reputation:
private getSomeData(): DataObjectArray[] {
return this.myService.something().map((response: Response) => {
return response.children;
});
}
Should be
private getSomeData(): Promise<DataObjectArray[]> {
return this.myService.something().map((response: Response) => {
return response.children;
});
}
Upvotes: 0