CDC is the right way to go. Here is the example above using it...
Required configuration for org:
- Go to Setup and type Change Data Capture in Quick Find then select it
- Type Opportunity in Type to filter list...
- Select Opportunity then click the Add (right-arrow) button
- Click Save
Here are the LWC component elements...
<?xml version="1.0" encoding="UTF-8" ?>
<LightningComponentBundle
xmlns="http://soap.sforce.com/2006/04/metadata"
fqn="scores"
>
<apiVersion>56.0</apiVersion>
<isExposed>true</isExposed>
<masterLabel>Magic Number</masterLabel>
<description>Whatever you want</description>
<targets>
<target>lightning__RecordPage</target>
</targets>
<targetConfigs>
<targetConfig targets="lightning__RecordPage">
<objects>
<object>Opportunity</object>
</objects>
</targetConfig>
</targetConfigs>
</LightningComponentBundle>
<template>
<div class="amazing-visualization">{magicNumber}</div>
</template>
import { api, LightningElement, wire } from 'lwc';
import { getRecord, getFieldValue } from 'lightning/uiRecordApi';
import { getRecord, getFieldValue, getRecordNotifyChange } from 'lightning/uiRecordApi';
import { subscribe, unsubscribe, onError } from 'lightning/empApi';
import MAGIC_NUMBER_FIELD from '@salesforce/schema/Opportunity.Magic_Number__c';
export default class MagicNumber extends LightningElement {
@api recordId;
@wire(getRecord, { recordId: '$recordId',[MAGIC_NUMBER_FIELD] }) opportunity;
channelName = '/data/OpportunityChangeEvent';
subscription = {}; // holds subscription, used for unsubscribe
connectedCallback() {
this.registerErrorListener();
this.registerSubscribe();
}
disconnectedCallback() {
unsubscribe(this.subscription, () => console.log('Unsubscribed to change events.'));
}
// Called by connectedCallback()
registerErrorListener() {
onError(error => {
console.error('Salesforce error', JSON.stringify(error));
});
}
// Called by connectedCallback()
registerSubscribe() {
const changeEventCallback = changeEvent => {
this.processChangeEvent(changeEvent);
};
// Sets up subscription and callback for change events
subscribe(this.channelName, -1, changeEventCallback).then(subscription => {
this.subscription = subscription;
});
}
// Called by registerSubscribe()
processChangeEvent(changeEvent) {
try {
const recordIds = changeEvent.data.payload.ChangeEventHeader.recordIds; // avoid deconstruction
if (recordIds.includes(this.recordId)) getRecordNotifyChange([{ recordId: this.recordId }]); // Refresh all components
} catch (err) {
console.error(err);
}
}
get magicNumber() {
return getFieldValue(this.opportunity.data, MAGIC_NUMBER_FIELD) || 42;
}
}