Angular, HttpClient problem z przechwyceniem odpowiedzi

0

Witam, jestem nowy jeśli chodzi o framework Angular. Już na starcie mam problem z pobieraniem danych z api.

Fragment kodu z serwisu:

public getTypes() : Observable<Type[]>
  {
    let url = "http://localhost:49193/api/book/GetTypes";
    return this.http.get<Type[]>(url);
  }

Fragment kodu z komponentu:

public types : Type[];

constructor(bookService : BookService)
  {
    this.bookService = bookService;
    this.getTypes();
    console.log("AppComponent types: " + this.types);
  }

public getTypes()
  {
    this.bookService.getTypes().subscribe(
      response => this.types = response
    );
  }

W konsoli dostaję wynik undefined.
Jednakże gdy zrobię coś takiego:

 public getTypes()
  {
    this.bookService.getTypes().subscribe(
      response =>
      {
        this.types = response
        console.log(response);
      }
    );
  }

w konsoli wypisują się pobrane dane z Api. Ponadto gdy dopisałem metodę, która tylko wpisywała do konsoli zawartość kolekcji types wywoływanej po naciśnięciu buttona dane wypisywały się również prawidłowo. Nie rozumiem dlaczego tak się dzieje. Może to być spowodowane tym, że dane ładują się do mojej lokalnej kolekcji, lecz trwa to jakiś czas i w momencie wypisywania ich w konstruktorze nie zdążyły się przypisać do lokalnej kolekcji ?

Z góry dziękuję za odpowiedź i pozdrawiam.

0

a nie powinno tam byc cos w stylu

public getTypes()
  {
    this.bookService.getTypes().subscribe(
      response => this.types = response.text();
    );
  }

albo

public getTypes()
  {
    this.bookService.getTypes().subscribe(
      response => this.types = response.getContent();
    );
  }

p.s. jeżeli mozesz jeszcze zaerocic z tej drogi to zawroc :) bo Angular to mina najgorsza wjaka mogłeś wdepnąć.

0

Dziękuję za odpowiedź, lecz niestety nie w tym leży problem.
Abstrahując od tego czy to dobry framework czy nie, chciałbym rozwiązać ten problem :) , bo już nie mam pomysłu co jest nie tak.
W wielu źródłach jakie sprawdzałem robiono analogicznie i nikt nie miał tego problemu co ja.

2

Masz dobrze skonfigurowane środowisko, wszystko wygląda cacy.
Jest tylko jeden problem... który leży w Twoim rozumowaniu.

Zobacz na ten kod:

public types : Type[];

constructor(bookService : BookService)
  {
    this.bookService = bookService;
    this.getTypes();
    console.log("AppComponent types: " + this.types);
  }

public getTypes()
  {
    this.bookService.getTypes().subscribe(
      response => this.types = response
    );
  }

JavaScript jest językiem wykonywanym asynchronicznie. Co to znaczy? Że Twój kod (context) nie będzie czekał, aż wszystko w nim się wykona. JS operuje na eventach, musisz mu dokładnie powiedzieć, kiedy dane zadanie się kończy np. za pomocą Promise (poczytaj).
Masz swój constructor() gdzie wywołujesz metodę this.getTypes();.
Zaraz linijkę niżej robisz console.log("AppComponent types: " + this.types);, oczekując, że tam jakiś magicznym sposobem dane się od razu pojawią.
Twój konstruktor jest wykonywany w całości od razu zaraz po utworzeniu instancji tej klasy (w Twoim wypadku komponentu) i nie ważne co się w nim robi. On tylko rozpoczyna request do serwera i idzie dalej.
Co to znaczy? Że po to subskrybujesz this.bookService.getTypes(), aby wiedzieć kiedy serwer odpowie i dopiero wtedy masz dostęp do danych od serwera. Twój konstruktor robi console.log() obiektu, w którym jeszcze nic nie ma - czyli public types : Type[];.
Jeżeli chciałbyś, aby on poczekał na zakończenie requestu (tak aby constructor wykonywał console.log() już po otrzymaniu danych) to poczytaj o Promise'ach oraz async await w JS (ES6+).

1

Dziękuje bardzo za odpowiedź.
Cały czas zakładałem właśnie, że to się wykona synchronicznie. Teraz już rozumiem, dzięki.

1 użytkowników online, w tym zalogowanych: 0, gości: 1