Wywołanie metody nie zwraca wartości do tablicy

0

Witam.

Mam taki problem.

Za pomocą Http zwracam dane. Wszystko działa sprawdzone za pomocą przeglądarki jednak nie mogę tego wyświetlić na froncie. Mam taki dziwny problem z którym nie mogę sobie poradzić nawet podczas debugowania.

Mam tablicę clientList i do niej teoretycznie powinny zostać zwrócone dane(zasubskrybowane).

Wywołując API dostaję undefined. Przypisałem sobie buttona do zapytania HTTP.

Moje pierwotne zapytanie przypisane do buttona wygląda tak :

Tu HMTL :

<button (click)= "getClients()" ></button>

I mój komponent z metodą :

import { Component, OnInit } from '@angular/core';
import {MapsAPILoader} from '@agm/core';
import { ClientService } from '../Services/ClientService';
import { Client } from '../Models/Client';
import { HttpClient } from '@angular/common/http';

@Component({
  selector: 'app-map',
  templateUrl: './map.component.html',
  styleUrls: ['./map.component.css']
})
export class MapComponent implements OnInit {

  clientList: Array<Client>;


  constructor(private client: ClientService){}

  ngOnInit(): void {
    // this.getClients();
  }


  // tslint:disable-next-line: typedef
  getClients(){
    this.client.getClients().subscribe(clients => this.clientList = clients);
    this.loopByArray();
  }


   
     loopByArray(){
      for (let index = 0; index < this.clientList.length; ++index) {
        let value = this.clientList[index];
        console.log(index, value);
      }
    }
}

Jeżeli wywołuję buttona tak jak napisałem dostaję undefined. Jeśli jednak zmienię tylko jeden znak podczas debugowania czyli dopiszę jeszcze jeden znak równości :

Stary :
this.client.getClients().subscribe(clients => this.clientList = clients);

Nowy :
this.client.getClients().subscribe(clients => this.clientList == clients);

I puszczę to jeszcze raz(wcisnę button) to otrzymuję normalnie klientów bez problemu :

screenshot-20201124213021.png

Niestety porawiając kod dodaję dokładnie ten sam błąd i znowu undefined(nawet jak puszczę ją kilka razy) . Nie ogarniam o co chodzi. Czy tablicę trzeba wygenerować na samym początku ? Bo już nie rozumiem tego do końca.

1

.subscribe() działa asynchronicznie - przekazana jako parametr funkcja zostanie uruchomiona kiedyś w przyszłości (tj. gdy dana wartość będzie dostępna), nie od razu - w porównaniu do this.loopByArray();, które uruchamiasz od razu, nie czekając na dane.

Najprostszym rozwiązaniem byłoby przeniesienie wywołania this.loopByArray(); do środka closure'a:

this.client.getClients().subscribe(clients => {
  this.clientList = clients;
  this.loopByArray();
});

W celu zwizualizowania różnicy, możesz dorzucić np. console.log():

console.log('before subscribe()');

this.client.getClients().subscribe(clients => {
  console.log('inside subscribe()');
});

console.log('after subscribe()');

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