I am trying to retrieve data from an API and store it to an array in Angular. I have looked at tutorials and done what they said, but any time I try to log the array to the console (or use it anywhere else) it shows that it is empty (which is what I initialize it as before changing the value). I have tried moving the console.log command to many different places in file to see if that was the issue but it hasn't made any difference. The code from my app.component.ts file is below.
import { Component, OnInit } from '@angular/core';
import { ApiService } from './api-service.service';
import { User } from 'src/User';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
title = 'apitable2';
users: User[] = [];
constructor(private apiService: ApiService) {}
ngOnInit(): void {
this.onGetUsers()
console.log(this.users)
}
onGetUsers() {
this.apiService.getUsers().subscribe(
response => {this.users = response}
)
}
}
Any help would be much appreciated!
EDIT: I should also mention that logging to the console is not the end goal, I should have been more clear. I am trying to pass the array this.users to a child component, but whenever I do so it shows that the array is empty still. So I am looking for a way to pass the array after the function onGetUsers() has completely finished running.
CodePudding user response:
You should console.log after the data comes because when you are working with API, these kinds of activities are async, which means a response is not provided immediately after you call function.
onGetUsers() {
this.apiService.getUsers().subscribe(
response => {
this.users = response
console.log(this.users);
}
)
}
CodePudding user response:
When you call your API, the code inside subscribe() doesn't run until a response is received from the server. Try moving your console.log statement inside the subscribe handler, and you should see the values you're expecting:
onGetUsers() {
this.apiService.getUsers().subscribe(
response => {
this.users = response;
console.log(this.users);
}
)
}
In order to understand what is happening here, you really need to understand rxJS observables. The call to getUsers() is returning an observable, which you are subscribing to. Your code continues to run which is why your console.log() call happens before the array has been populated, and it's only when the API has a result for you that the code inside subscribe() runs.
CodePudding user response:
If users list should be fetched at the initialization of your app component (it seems to be the case, because you call it inside OnInit
),
you can simplify your code and use directly Observable
returned by the HttpClient.
Service api.service.ts
:
@Injectable()
export class ApiService {
...
getUsers(): Observable<User[]> {
return this.httpClient.get<User[]>('...url...');
}
}
Component app.component.ts
:
export class AppComponent implements OnInit {
users$ = this.apiService.getUsers();
constructor(private apiService: ApiService) {}
}
Template app.component.html
:
<child-cpt [users]="users$ | async"></child-cpt>
And if you want to check value returned before displaying your child component, you can do :
<ng-container *ngIf="users$ | async as users">
<!-- only if users is defined -->
<child-cpt [users]="users"></child-cpt>
</ng-container>