I'm trying to return the 'scorearray' array in this method, but what I'm getting is something called a 'subscriber'. I'm new to all this. Please help.
My method:
public GetScores():any {
// var result = await this.topbarService.getPatientData();
var patientID = "DummyID 1"//result.Data.Demographics.Identifers.patientID;
var apiUrl = 'questionaire/GetPatientHistory'
return this.http.post(apiUrl, { Id: patientID }).subscribe(data => {
var data2: any = data;
var scorearray = []
for (var i = 0; i < data2.length; i ) {
var objtemp = data2[i]
scorearray.push(objtemp.score)
}
return scorearray
});
}
CodePudding user response:
You can return Oberservation by return this.http.post(apiUrl, { Id: patientID }). then you can call subscribe if you actually wanna get the data.
CodePudding user response:
The HttpClient
service generally returns an RxJS Observable
, which is what post
returns here. You can subscribe
to an Observable
, which executes the request and performs the callback function on receiving a response.
You should leave subscribing to the latest moment possible, and preferably only subscribe in the HTML file using the async
pipe (more on that later). To achieve what you're trying to do here, it's better to use the pipe
method, which allows you to transform the received data. pipe
produces a new Observable
which can be subscribed to later.
pipe
takes operators
as arguments which will be executed on the received data. The most common is map
which simply takes the data, and returns something else. That's the only operator we need in this case. More info here: https://rxjs.dev/guide/operators
getScores(): Observable<any[]> {
const patientID = 'DummyID 1';
const apiUrl = 'questionaire/GetPatientHistory';
return this.http
.post<any[]>(apiUrl, { Id: patientID })
.pipe(map((data: any[]) => data.map((objTemp) => objTemp.score)));
}
I've streamlined your callback function into the one liner data.map((objTemp) => objTemp.score)
. That's using the Array.map()
function, not to be confused with the map
RxJS operator. As a side note var
is legacy code that should be avoided. Use const
when possible and let
otherwise.
Notice how this function returns an Observable
, so to get the data you need to subscribe somehow. The simplest way to do that is to assign the Observable
to a variable and use the async
pipe in HTML. To show you how it's normally done, I'll put this function in a service as well.
Service
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/internal/Observable';
import { map } from 'rxjs/internal/operators/map';
@Injectable({
providedIn: 'root',
})
export class MyService {
constructor(private http: HttpClient) {}
getScores(): Observable<any[]> {
const patientID = 'DummyID 1';
const apiUrl = 'questionaire/GetPatientHistory';
return this.http
.post<any[]>(apiUrl, { Id: patientID })
.pipe(map((data: any[]) => data.map((objTemp) => objTemp.score)));
}
}
Component TS
export class OneComponent {
constructor(private ms: MyService) {}
scoreArray = new Observable<any[]>();
ngOnInit() {
this.scoreArray = this.ms.getScores();
}
}
Component HTML
<pre>{{ scoreArray | async | json }}</pre>
Here's an example using the jokes API https://stackblitz.com/edit/angular-ivy-wuwtqv?file=src/app/my.service.ts