public with sharing class lwcLifetimeSpendingController {
@AuraEnabled (cacheable=true)
public static List<AggregateResult> getAccountLifetimeSpending(){
return [SELECT SUM(Service_Amount__c) Service, SUM(Subscription_Booking__c) Subscription SUM(Renewal_Amount_Xactly__c) Renewal FROM Opportunity WHERE AccountId = '0018000001G9dZUAAZ' and isClosed=true and isWon=true];
}
} //class
import { LightningElement,track,wire } from 'lwc';
import { getSObjectValue } from '@salesforce/apex';
import { loadScript } from 'lightning/platformResourceLoader';
import chartjs from '@salesforce/resourceUrl/chart';
import getAccountLifetimeSpending from '@salesforce/apex/lwcLifetimeSpendingController.getAccountLifetimeSpending';
const generateRandomNumber = () => {
return Math.round(Math.random() * 100);
};
export default class LifetimeSpending extends LightningElement {
@track lifetimeAggResult;
@track error;
serviceAmount;
subcriptionAmount;
@wire(getAccountLifetimeSpending) lifetimeAggregateResult({error,data}) {
if (data) {
this.lifetimeAggResult = data;
console.log('this.lifetimeAggResult: ' + this.lifetimeAggResult[0].Service);
this.serviceAmount = this.lifetimeAggResult[0].Service;
this.subcriptionAmount = this.lifetimeAggResult[0].Subscription;
this.error = undefined;
} else if (error) {
this.lifetimeAggResult = undefined;
this.error = error;
console.log('Error: ' + this.error);
}
}
chart;
chartjsInitialized = false;
config = {
//type: 'doughnut',
type: 'bar',
data: {
datasets: [
{
data: [
this.serviceAmount,
this.subcriptionAmount
],
backgroundColor: [
'rgb(255, 99, 132)',
'rgb(255, 159, 64)',
'rgb(255, 205, 86)',
'rgb(75, 192, 192)',
'rgb(54, 162, 235)'
],
label: 'Dataset 1'
}
],
labels: ['Service', 'Subscription', 'Private Training', 'Public Training', 'Renewal']
},
options: {
responsive: true,
legend: {
position: 'right'
},
animation: {
animateScale: true,
animateRotate: true
}
}
};
renderedCallback() {
if (this.chartjsInitialized) {
return;
}
this.chartjsInitialized = true;
loadScript(this, chartjs)
.then(() => {
const ctx = this.template
.querySelector('canvas.donut')
.getContext('2d');
this.chart = new window.Chart(ctx, this.config);
})
.catch(error => {
this.error = error;
});
}
} //end export
<template>
<lightning-card title="Lifetime Spending" icon-name="custom:custom19">
<div class="slds-m-around_medium">
<canvas class="donut" lwc:dom="manual"></canvas>
</div>
<template if:true={error}>
<c-error-panel errors={error}></c-error-panel>
</template>
</lightning-card>
</template>
The first code sample is a simple apex class lwcLifetimeSpendingController return List
The second code sample is LWC JS file.
The third code sample is the HTML file.
When I use data: [this.serviceAmount, this.subscriptionAmount]
in the chart's data config, this.serviceAmount
and this.subscriptionAmount
do not return any data. The chart is just blank.
What can I do differently do render dynamic data from variables in the JS file?
Best Answer
Fetching data is asynchronous. It’s nearly always the case that
connectedCallback
is invoked prior to@wire
provisioning a value.This means you’re configuring the chart with no data. Data then arrives but you don’t pass it to the chart.
Checkout https://www.chartjs.org/docs/latest/developers/updates.html for how to update an existing ChartJS instance with new data. You need to do something comparable in
lifetimeAggregateResult()