1👍
Expanding from my comment, there are multiple issues here
-
The data is assigned asynchronously. You need to make sure it’s available by the time the
this.data
is initialized. You could use higher order mapping operatorswitchMap
to make one observable depend on another. -
You’re trying to access properties from a string produced by serializing an array. You need to access the object element to get it’s properties.
Try the following
export class ChartComparatifComponent implements OnInit, OnDestroy {
...
ngOnInit() {
this.themeSubscription = this.getPlanet().pipe(
switchMap(chartData =>
this.theme.getJsTheme().pipe(
map(config => ({ config: config, chartData: chartData})) // <-- return data and config
)
)
).subscribe({
next: ({config, chartData}) => {
const colors: any = config.variables;
const chartjs: any = config.variables.chartjs;
this.data = {
labels: ['Temperature Maximum', 'Temperature Moyenne', 'Temperature Minimum'],
datasets: [{
data: [chartData.tempMin, chartData.tempMoy, chartData.tempMax], // test
label: 'Mercure',
backgroundColor: 'rgba(143, 155, 179, 0.24)',
borderColor: '#c5cee0',
}, {
data: [chartData.tempMin, chartData.tempMoy, chartData.tempMax], // test
label: 'Venus',
backgroundColor: 'rgba(255, 170, 0, 0.24)',
borderColor: '#ffaa00',
}, {
data: [chartData.tempMin, chartData.tempMoy, chartData.tempMax], // test
label: 'Terre',
backgroundColor: 'rgba(0, 149, 255, 0.48)',
borderColor: '#0095ff',
}, {
data: [chartData.tempMin, chartData.tempMoy, chartData.tempMax], // test
label: 'Mars',
backgroundColor: 'rgba(0, 214, 143, 0.24)',
borderColor: '#00d68f',
}],
};
this.options = {
tooltips: {
enabled: true,
mode: 'single',
position: 'nearest',
callbacks: {
label: function (tooltipItems) {
return tooltipItems.yLabel + ' c°';
},
},
},
responsive: true,
maintainAspectRatio: false,
scales: {
xAxes: [
{
gridLines: {
display: true,
color: chartjs.axisLineColor,
},
ticks: {
fontColor: chartjs.textColor,
},
},
],
yAxes: [
{
gridLines: {
display: true,
color: chartjs.axisLineColor,
},
ticks: {
fontColor: chartjs.textColor,
},
},
],
},
legend: {
labels: {
fontColor: chartjs.textColor,
},
},
};
}
})
}
getPlanet(): Observable<any> { // <-- return the observable here
this.planetService.getPlanets().pipe(
map(res =>
res.data.filter(e => e.name === 'Mercure')[0] // <-- use the first element of the array (array apparantly has only one element)
)
)
}
}
Update: use array with multiple element
As said in the comment, you could use Array#map
to convert all the elements in the array to the format expected by ChartJS.
Try the following
export class ChartComparatifComponent implements OnInit, OnDestroy {
...
planetOptions = { // <-- object to hold planet specific properties
Mercure: {
backgroundColor: 'rgba(143, 155, 179, 0.24)',
borderColor: '#c5cee0'
},
Venus: {
backgroundColor: 'rgba(255, 170, 0, 0.24)',
borderColor: '#ffaa00',
},
Terre: {
backgroundColor: 'rgba(0, 149, 255, 0.48)',
borderColor: '#0095ff'
},
Mars: {
backgroundColor: 'rgba(0, 214, 143, 0.24)',
borderColor: '#00d68f'
}
};
ngOnInit() {
this.themeSubscription = this.getPlanet().pipe(
switchMap(chartData =>
this.theme.getJsTheme().pipe(
map(config => ({ config: config, chartData: chartData})) // <-- return data and config
)
)
).subscribe({
next: ({config, chartData}) => {
const colors: any = config.variables;
const chartjs: any = config.variables.chartjs;
this.data = {
labels: ['Temperature Maximum', 'Temperature Moyenne', 'Temperature Minimum'],
datasets: chartData, // <-- use modified chart data here
};
this.options = {
tooltips: {
enabled: true,
mode: 'single',
position: 'nearest',
callbacks: {
label: function (tooltipItems) {
return tooltipItems.yLabel + ' c°';
},
},
},
responsive: true,
maintainAspectRatio: false,
scales: {
xAxes: [
{
gridLines: {
display: true,
color: chartjs.axisLineColor,
},
ticks: {
fontColor: chartjs.textColor,
},
},
],
yAxes: [
{
gridLines: {
display: true,
color: chartjs.axisLineColor,
},
ticks: {
fontColor: chartjs.textColor,
},
},
],
},
legend: {
labels: {
fontColor: chartjs.textColor,
},
},
};
}
})
}
getPlanet(): Observable<any> { // <-- return the observable here
this.planetService.getPlanets().pipe(
map(res =>
res.data
.filter(e => Object.keys(this.planetOptions).includes(e.name)) // <-- use only planets available in `this.planetOptions`
.map(e => ({ // <-- format expected by ChartJS
...this.planetOptions[e.name],
data: [e.tempMin, e.tempMoy, e.tempMax],
label: e.name
}))
)
)
}
}
Source:stackexchange.com