Returning the value directly is not possible due to the asynchronous nature of the call.
An async call runs in the background (scheduled for later execution) while your code continues.
It's important to note that such code cannot be placed directly in the class; it should be moved into a method or the constructor instead.
One workaround is to avoid directly calling subscribe()
and instead use an operator like map()
.
export class DataComponent{
someMethod() {
return this.http.get(path).map(res => {
return res.json();
});
}
}
Furthermore, you can chain multiple .map
calls with the same Observables for better code clarity and separation. For example:
validateResponse = (response) => validate(response);
parseJson = (json) => JSON.parse(json);
fetchUnits() {
return this.http.get(requestUrl).map(this.validateResponse).map(this.parseJson);
}
This approach allows the observable to be returned for subscription by the caller.
export class DataComponent{
someMethod() {
return this.http.get(path).map(res => {
return res.json();
});
}
otherMethod() {
this.someMethod().subscribe(data => this.data = data);
}
}
The subscriber can also be located in another class for brevity.
data => this.data = data
and
res => return res.json()
are arrow functions, similar to normal functions. These functions are passed to subscribe(...)
or map(...)
to be executed once data arrives from the observable response.
This explains why data cannot be returned directly, as it may not have been received yet when someMethod()
completes.