Search code examples
arraysangulartypescriptget

Cannot pass value from service to component


I'm learning to use Angular.
I've done some API with Spring-boot and I've created some components in Angular to view them, but I can't view anything.

I've created in angular a Service to do all the API calls.
In the service I've created an array of type any and set it empty

  luoghi : any[] = [];

then I do the GET request and in the method I assign the response value to the array:

getAllLuoghi(){
    this.http.get("http://localhost:9595/oota-reg/api/luoghi/all").subscribe({
      next : (response : any) =>{

        console.log(response);
        
        this.luoghi = response;
 
      },
      error : (error) => {
        console.log("Something went wrong..", error);
        
      }
    })
  }

Now I've created another two components, one is the Home component and the other is a Card component, basic stuff.

The home component is in charge to cycle all the elements in the array and for each element put in screen a Card of Card components

    <div class="flex justify-center flex-wrap gap-5">
        @for (item of cards; track $index) {
            <app-card></app-card>
        }@empty {
            <p>none</p>
        }
    
    </div>

But here's where is the problem in the home.component.ts what I wanted to do is create an array named cards,
inject the Service and give to cards the value of the array present in the Service after the GET call.

 private serviceLuoghi : LuoghiServiceService = inject(LuoghiServiceService);

  public cards : any[] = [];

  ngOnInit(): void {

    this.serviceLuoghi.getAllLuoghi();

    this.cards= this.serviceLuoghi.luoghi

    console.log(this.cards);
        
  }

But the card array is empty.
How can I pass the data?


Solution

  • The code inside the subscribe is asynchronous (waits for API to complete) the code outside is synchronous ( does not wait ) so I hope you see the problem, we are accessing the property before the API completes. So the solution for this is to moving the assignment code into the subscribe, so that it gets assigned after the API call is done.

    getAllLuoghi(){
      return this.http.get("http://localhost:9595/oota-reg/api/luoghi/all")
    }
    

    Now the service returns an observable which we can subscribe inside the component, better to subscribe to observables inside the component rather than services.

      ngOnInit(): void {
        this.serviceLuoghi.getAllLuoghi().subscribe({
          next : (response : any) =>{
            console.log(response);
            this.serviceLuoghi.luoghi = response; // can remove if not needed!
            this.cards= response;
            console.log(this.cards);
          },
          error : (error) => {
            console.log("Something went wrong..", error);
          }
        })
      }