W komponencie.ts mam tę metodę, która wywołuje interfejs API i pracuje z odpowiedzią. Otrzymuję pustą tablicę, ponieważ nie czeka na subskrypcję

disp(): String[] {
    let scores: String[] = [];
    this.assessmentService.getPrograms().subscribe(
      (res: AssessmentResponse[]) => {
        res.map(
          function (t) {
            const body = `{id: ${t.id}, name: "${t.name}"}`;
            scores.push(body);
          })
        return scores;
      },
      (err: HttpErrorResponse) => {
        if (err.error instanceof Error) {
          console.log("Client-side error occured.");
        } else {
          console.log("Server-side error occured.");
        }
      });
    console.log("returned");
    return scores;
  }

Chcę przechowywać tablicę powrotu z disp

 programList$ = observableOf(this.disp);

A potem używam programList $ do ustawiania wartości opcji, publikuję mały fragment kodu, ponieważ ma wiele zakładek

 tabs: TabType[] = [
    {
      label: 'Assign Program',
      fields: [
        {
          fieldGroupClassName: 'display-flex',
          fieldGroup: [
            {
              className: 'flex-1',
              key: 'campaign',
              type: 'select',
              templateOptions: {
                label: 'Campaign',
                placeholder: 'Select Campaign',
                // description: 'Campaign Name',
                required: true,
                options: this.programList$,

To moja usługa

 public  getPrograms(): Observable<AssessmentResponse[]> {

         return this.http.get(this.endpoint,this.headers.httpOptions)
         .pipe(map((data: EmbeddedAssessmentsResponse) => data._embedded.programs));          
    }

PS: Jestem nowy w kątowym i maszynopisie, każda pomoc jest mile widziana.

0
Umesh Kumar 20 listopad 2019, 17:04
Twój kod nie ma sensu, jeśli chcesz czekać na wywołanie subskrypcji. Gdzie jest wywoływana funkcja disp()?
 – 
ukn
20 listopad 2019, 17:09
Zaktualizowany, z którego wywoływany jest disp
 – 
Umesh Kumar
20 listopad 2019, 17:43

4 odpowiedzi

Jeśli pracujesz z danymi asynchronicznymi, Twoja metoda disp() powinna zwrócić Observable i powinieneś ją zasubskrybować na końcu swojego łańcucha.

Możesz też utworzyć właściwość scores i przypisać dane z interfejsu API w metodzie subskrypcji.

0
igor_c 20 listopad 2019, 17:11

Jeśli twoja programList$ jest Observable, twoja metoda disp() powinna zwrócić Observable: programList$ = this.disp();

disp(): Observable<String[]> {
  return this.assessmentService.getPrograms().pipe(
    map((res: AssessmentResponse[]) => {
        return res.map(t => `{id: ${t.id}, name: "${t.name}"}`);
      }),
    catchError((err: HttpErrorResponse) => {
        if (err.error instanceof Error) {
          console.log("Client-side error occured.");
        } else {
          console.log("Server-side error occured.");
        }
        return of([]);
      });
  );
0
HTN 20 listopad 2019, 18:08

Ponieważ wywołanie zwrotne subscribe jest wykonywane asynchronicznie, twoja tablica będzie pusta, jeśli spróbujesz ją odczytać przed wykonaniem wywołania zwrotnego.

Po prostu utwórz właściwość programList w swoim komponencie i przypisz dane zwrócone z API, gdy wywołanie zwrotne subskrypcji jest wykonywane, a następnie wywołaj funkcję, aby utworzyć tablicę tabs. Możesz spróbować czegoś takiego:

programList: string[];
tabs: TabType[];

disp(): void {
    this.assessmentService.getPrograms().subscribe(
      (res: AssessmentResponse[]) => {
        let scores: String[] = [];
        res.map(
          function (t) {
            const body = `{id: ${t.id}, name: "${t.name}"}`;
            scores.push(body);
          })
        this.programList = scores;
        this.createTabsArray();
      },
      (err: HttpErrorResponse) => {
        if (err.error instanceof Error) {
          console.log("Client-side error occured.");
        } else {
          console.log("Server-side error occured.");
        }
      });
}

createTabsArray(): void {
    this.tabs = [
    {
      label: 'Assign Program',
      fields: [
        {
          fieldGroupClassName: 'display-flex',
          fieldGroup: [
            {
              className: 'flex-1',
              key: 'campaign',
              type: 'select',
              templateOptions: {
                label: 'Campaign',
                placeholder: 'Select Campaign',
                // description: 'Campaign Name',
                required: true,
                options: this.programList,
                ...
                ...
                }
            ...
            ...
            }]
}
0
Stefano Populin 20 listopad 2019, 18:35

Jednym ze sposobów jest użycie wzorca async / wait, aby uzyskać dane.

  private async fetchData(){
    const data = await this.httpClient.get(this.apiUrl).toPromise();
    console.log("Data: " + JSON.stringify(data)); 
  }

Nie radziłbym jednak tego. Możesz spróbować wysłać wyniki do innej funkcji i tam obsłużyć dane

Na przykład:

disp(): String[] {
this.assessmentService.getPrograms().subscribe(
  (res: AssessmentResponse[]) => {

    handleResponse(res);
  },
  (err: HttpErrorResponse) => {
    if (err.error instanceof Error) {
      console.log("Client-side error occured.");
    } else {
      console.log("Server-side error occured.");
    }
  });
  // return scores;
}

Twoja odpowiedź uchwytu zrobi wszystko, co chcesz, aby zrobiła dla twojego komponentu.

-1
Athanasios Kataras 20 listopad 2019, 17:10