+ Start a Discussion
BrianWXBrianWX 

How to Use AggregateResult in LWC

I built a custom class and method to return the aggregate data to plot a chart using LWC.  For the purpose of example, I hardcode the AccountId for now.
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  FROM Opportunity WHERE accountid = '0018000001G9dZUAAZ' and isclosed=true and iswon=true];
    }
}

Here's my JS file.  How do I retrieve the aggregate values from the custom apex controller and use in the JS?  I tried getSObjectValue, but that did not work as it worked only with field data from the return Object.
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 {    
    @wire(getAccountLifetimeSpending) lifetimeAggregateResult;
    @track error;
    
     //getSObjectValue does not work in this scenario
} //end export

Here's the sample of the HTML file
<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>


 
Alain CabonAlain Cabon
@BrianWX

property Or Function after @wire.

@wire(getAccountLifetimeSpending) lifetimeAggregateResult;  // property

or function:  wiredAccountLifetimeSpending({ error, data })
@track lifetimeAgg; 
@track error;

@wire(getAccountLifetimeSpending)
    wiredAccountLifetimeSpending({ error, data }) {
        if (data) {
            this.lifetimeAgg = data;
            console.log('data:' + JSON.stringify(data));
            this.error = undefined;
            // other treatment here ...         
        } else if (error) {
            this.lifetimeAgg = undefined;
            this.error = error;
        }
    }

https://developer.salesforce.com/docs/component-library/documentation/lwc/lwc.apex

import apexMethod from '@salesforce/apex/Namespace.Classname.apexMethod';
@wire(apexMethod, { apexMethodParams })
         propertyOrFunction;

 
BrianWXBrianWX
Thanks, @Alain Cabon.

I updated using the @wire(apexMethod, {apexMethodParams}) it was able to retrieve data and assign data to local var.
lifetimeAggResult; 
serviceAmount; 
subscriptionAmount; 
this.lifetimeAggResult = JSON.parse(JSON.stringify(data)); 
this.serviceAmount = this lifetimeAggResult[0].Service; 
this.subscriptionAmount = this.lifetimeAggResult[0].Subscription;

One thing I could not figure out why it could not get data from the local var in the code below.  It could not render the values for the line data: [this.serviceAmount, this.subscriptionAmount]
config = {
        //type: 'doughnut',        
        type: 'bar',
        data: {                        
            datasets: [
                {                    
                    data: [this.serviceAmount, this.subscriptionAmount],
                    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
            }
        }
    };

 
Alain CabonAlain Cabon
Not sure you need to do this: this.lifetimeAggResult = JSON.parse(JSON.stringify(data));

console.log(JSON.stringify(data));   helps above all to verify the content 

but you can use directly: this.lifetimeAggResult = data;  very likely.

this.lifetimeAggResult = data; 
this.serviceAmount = this lifetimeAggResult[0].Service;
this.subscriptionAmount = this.lifetimeAggResult[0].Subscription;
 
Iqbal 0 BashaIqbal 0 Basha
@BrianWX - Can you share the code, I am looking for basic example code to implement charts using chart js and data from apex, also update chart from new data. If you would share full example (Html, JS, and Apex Class) that would be fine.
BrianWXBrianWX
@Iqbal - You can download lwc-recipes, examples developed by Salesforce, on github https://github.com/trailheadapps/lwc-recipes and deploy to a scratch org.  They provided great examples on using chartjs.  The examples in lwc-recipes gave me a great starting point.
Rohit RadhakrishnanRohit Radhakrishnan
@BrianWX, Please check this blog for the use of Aggregate query and in LWC to draw chart using ChartJS.
Dynamic Chart in LWC With Multiple Datasets Using ChartJS (https://salesforcerealm.com/2020/12/09/chart-in-lwc-using-chartjs/)