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?
CodePudding user response:
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 undifined
right?
doing subscribe()
is similar to a setTimeout
since both 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
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
CodePudding user response:
You can encapsulate the final manipulation inside the "finaly" in subscribe.
something 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]
}
);
Or just
this.dataService.getData(this.id).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]
}
);
Note that the "finally" doesn't receive any parameters, it only serves to do manipulations after receiving success or error from the observable