Search code examples
angulartypescriptfrontendobservable

Subscription of observable returns undefined


I use a service to fill my observable with data from the backend. The backend is delievering the correct data. Now I want to take the values of the observable and build a piechart.

The part of the Code looks like this:

this.dataSet = this.dataService.getData(this.id);
this.dataSet.subscribe(
x => this.rightData = x.rightCount,
x => this.wrongData = x.wrongCount,
);
console.log('First value: '+ this.rightData);
console.log('Second value: '+ this.wrongData);
this.pieChartData = [this.rightData, this.wrongData];

It doesn't work and the console output is:

First Value: undefined
Second Value: undefined

But when I change the code to the following, the console log shows the right data:

this.dataSet = this.dataService.getData(this.id);
this.dataSet.subscribe( 
x => console.log(x.rightCount),
x => console.log(x,wrongCount),
);

Output:

3
7

Additional code:

export interface Counter {
  rightCount: number;
  wrongCount: number;
}

dataSet: Observable<Counter> = of();

The service looks like:

getData(id: number): Observable<Counter> {
    return this.http.get<Counter>(`/backend/getData?id=${id}`);
  }

The firefox log shows me, the backend returns:

{"rightCount":3,"wrongCount":7}

Do you have an Idea where I make a mistake?


Solution

  • This behaviour is normal since your code (subscribe) runs asynchronously. It would be the same as:

    let test;
    setTimeout(() => {this.test = "hello"}, 1000);
    console.log(test);
    

    The code above would print undefined right?

    Doing subscribe() is similar to a setTimeout since both pieces of code runs asynchronously.

    Also if you would do:

    this.dataSet.subscribe(
        x => console.log('test1')
    );
    console.log('test2');
    

    The output would be: test2 test1 because the code inside subscribe runs asynchronously

    The correct code in your case would be:

    this.dataService.getData(this.id).subscribe(
      x => {
        this.rightData = x.rightCount;
        console.log('First value: '+ this.rightData);
        // this.wrongData is undefined here
        this.pieChartData = [this.rightData, this.wrongData];
      },
      err => {
        this.wrongData = x.wrongCount;
        console.log('Second value: '+ this.wrongData);
        // this.rightData is undefined here
        this.pieChartData = [this.rightData, this.wrongData];
      }
    );
    
    

    please note that the Second value / wrongData will only occurr if an error is thrown in this.dataService.getData