1

i have this service to get data from the api and save it into arrays afterwards:

export class DataService {
constructor(private http: HttpClient) { }

readonly baseURL = "https://localhost:44302/api";
books: Book[];
users: User[];
cards: Card[];
postId: number;

httpOptions = {
  headers: new HttpHeaders({
    'Content-Type': 'application/json'
  })
}

getBooks() {
  return this.http.get(this.baseURL + '/books');
}
getCards() {
  return this.http.get(this.baseURL + '/cards');
}
getUsers() {
  return this.http.get(this.baseURL + '/users');
} 
getData() {
  const observableList: Observable<any>[] = [];

  observableList.push(this.getBooks());
  observableList.push(this.getUsers());
  observableList.push(this.getCards());

  forkJoin(observableList).subscribe(resultList => {
    this.books = resultList[0] as Book[];
    this.users = resultList[1] as User[];
    this.cards = resultList[2] as Card[];
  });
}

in my component, i run the getData method and try to console.log the data but it keeps saying that the data is undefined, even though the api data shows up in the debugging-network tab:

export class MainComponent implements OnInit {
books: Book[];
users: User[];
cards: Card[];
selectedBook: Book;
display: boolean = false;
selectedUser: User;

constructor(public dataService: DataService) { }

ngOnInit() {
  this.dataService.getData();
  //Save data in local component arrays
  this.books = this.dataService.books;
  this.users = this.dataService.users;
  this.cards = this.dataService.cards;

  console.log(this.books); // ==> "undefined"
  }
3
  • 1
    You really don’t want to subscribe in your service. Best thing to do is have your service return the forkJoin so return forkJoin(observableList) and subscribe to that in your component Commented Oct 13, 2021 at 9:32
  • alright thanks Mike. So in the service i just do return forkJoin(observableList);" and on my component i say: ` this.dataService.getData.subscribe((result) => { this.books = resultList[0] as Book[]; this.users = resultList[1] as User[]; this.cards = resultList[2] as Card[]; }` Commented Oct 13, 2021 at 9:35
  • I just tried it, it keeps saying "undefined" Commented Oct 13, 2021 at 9:42

1 Answer 1

2

The arrays assigned within the component (after the service call) will already be executed before the service with getData() completes subscribing to the three observables. That is why they are assigning to undefined data.

In your service, modify it to return just the observable:

getData() {
  const observableList: Observable<any>[] = [];

  observableList.push(this.getBooks());
  observableList.push(this.getUsers());
  observableList.push(this.getCards());

  return forkJoin(observableList);
}

In your component then subscribe to the joined data calling getDate() within a subscriber:

this.dataService.getData()
  .subscribe(({resultOne, resultTwo, resultThree}) => {
     //Save data in local component arrays
     this.books = resultOne;
     this.users = resultTwo;
     this.cards = resultThree;
  });
}
Sign up to request clarification or add additional context in comments.

2 Comments

thanks andrew! Now i can do a console.log(result) in the .subscribe block and it shows the data. But if i want to use the data outside the .subscribe block for example console.log(this.books) it still says undefined. How am i able to send the received data to another service and modify it, when the data is undefined? Or do i have to do everything in the subscribe block?
You can either fire another observable (use a Subject or a BehaviorSubject) within the subscribe() { .. } block and subscribe to it with another subscription in ngInit() or call the other services through a user-triggered event handler within your component. This way you can process the results after they are received within your component.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.