I have problem with fetching the web API output using observable in angular typescript.
I'd like to fetch the value that will be returned by the first observable then pass its value to another observable. So far, this is what I have written.
let output: any;
let output2: any;
_httpClient.get('http://localhost:5000/api/mycontroller')
.subscribe((output_1) => {
output = output_1;
});
alert(output);
_httpClient.get('http://localhost:5000/api/mycontroller2'+output)
.subscribe((output_2) => {
output2 = output_2;
});
alert(output2);
I place an alert function below each observable subscribed to check the output returned of each response.
but when I execute it and check the output in the alert box, it gives undefined value to each.
how can I force observable to give the output that will come from my web API?
You can use an operator such as switchMap which per documentation "Maps to observable, complete previous inner observable, emit values". Using switchMap
it will switch to the 2nd HttpClient
call mapping the first observable, when the source of the first HttpClient
calls emits. If a new initial/outer request is executed, it will cancel the in-flight/in-process request.
Keep in mind, the way your alert()
statements are set up, they will simply not work as alert()
will execute before the requests have completed, hence the undefined
. You'd need to execute alert()
or similar within subscribe
or utilize operators such as do
/tap
to ensure the data has actually been returned.
import { switchMap } from 'rxjs/operators';
_httpClient.get('http://localhost:5000/api/mycontroller')
.pipe(
switchMap(output => _httpClient.get('http://localhost:5000/api/mycontroller2' + output))
)
.subscribe(output2 => alert(output2));
If you need to save the outputs to some local class property, you can utilize do/tap to perform an action before/after data is returned/mapped/processed.
import { switchMap, tap } from 'rxjs/operators';
_httpClient.get('http://localhost:5000/api/mycontroller')
.pipe(
tap(output => {
console.log(output);
this.output = output;
}),
switchMap(output => _httpClient.get('http://localhost:5000/api/mycontroller2' + output)),
tap(output2 => {
console.log(output2);
this.output2 = output2;
})
)
.subscribe(output2 => alert(output2));
For completeness of the accepted answer, other alternatives to switchMap
should be mentioned as well.
In contrast to switchMap
, the mergeMap
(also called flatMap
) operator will NOT be cancelled if the "outer observable" emits a second time before the "inner observable" completes. This may not be important in the case of HttpClient.get
, because it typically only emits once, thus never triggering the inner observable again.
However, be aware of the difference between switchMap
and mergeMap
when continuing working with RxJS operators, especially when dealing with a sequential stream of data.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With