3👍
✅
look the problem is that your numberByStatus
object reference doesn’t change when you are trying to push the items into labelsByStatus
or countsByStatus
arrays
try like this.
**at first import all of these items for both solutions
import { forkJoin } from 'rxjs/internal/observable/forkJoin';
import { map } from 'rxjs/operators';
and
numberByStatus : any;
labelsByStatus: String[] = [];
countsByStatus: number[] = [];
this.service.getStatus()
.subscribe((res: status[]) => {
const requestsList = []; // define the request list property and store all of the requests here
res.forEach(element => {
// push the request into the array
requestsList.push(
this.service.getCountByStatus(element.id).pipe(
map(count => {
// push the count into countsByStatus
this.countsByStatus.push(count);
// push the element.designation into labelsByStatus
this.labelsByStatus.push(element.designation);
// return the count and the corresponding element
// I think this can be helpfull. if you will need to know the count for the each element
return { element: element, count: count }
}))
);
});
// send all of the requests
forkJoin(requestsList).subscribe(
(response: {element: status, count: number}[]) => {
// and now this line will work only once
this.numberByStatus = { ...this.numberByStatus };
},
(err) => {
alert('Faild to load data');
}
);
}, (err) => {
alert('Faild to load data');
});
this.numberByStatus = {
labels: this.labelsByStatus,
datasets: [
{
data: this.countsByStatus,
backgroundColor: [
"#FF6384",
"#36A2EB",
"#FFCE56"
],
hoverBackgroundColor: [
"#FF6384",
"#36A2EB",
"#FFCE56"
]
}
]
};
or
numberByStatus : any;
labelsByStatus: String[] = [];
countsByStatus: number[] = [];
this.service.getStatus()
.subscribe((res: status[]) => {
const requestsList = []; // define the request list property and store all of the requests here
res.forEach(element => {
// push the request into the array
requestsList.push(
this.service.getCountByStatus(element.id).pipe(
map(count => {
// push the count into countsByStatus
this.countsByStatus.push(count);
// push the element.designation into labelsByStatus
this.labelsByStatus.push(element.designation);
// return the count and the corresponding element
// I think this can be helpfull. if you will need to know the count for the each element
return { element: element, count: count }
}))
);
});
forkJoin(requestsList).subscribe(
(response: {element: status, count: number}[]) => {
// and now this line will work only once
this.numberByStatus = {
labels: this.labelsByStatus,
datasets: [
{
data: this.countsByStatus,
backgroundColor: [
"#FF6384",
"#36A2EB",
"#FFCE56"
],
hoverBackgroundColor: [
"#FF6384",
"#36A2EB",
"#FFCE56"
]
}
]
};
},
(err) => {
alert('Faild to load data');
}
);
}, (err) => {
alert('Faild to load data');
});
0👍
The problem is due to the asynchronous nature of Angular. The chart is created before its labels
and the data
have been defined inside this.numberByStatus
.
There are basically two solutions to solve this issue.
- Make sure the chart is created only once
this.numberByStatus
is fully furnished. - Update the chart programmatically after
this.numberByStatus
is completely defined.
Without seeing more of your code, its hard to provide the best solution however. I also don’t know primeng-lts.
- You could try to only conditionally include the chart in your HTML template using
*ngIf
. It should evaluate totrue
only oncethis.numberByStatus
is ready to be used (solution 1). - In case you can obtain a reference to the
chart
object, invoke itsupdate()
method after you redefinedthis.numberByStatus
(solution 2).
Source:stackexchange.com