Skip to content

Instantly share code, notes, and snippets.

@renatoliveira
Created March 27, 2019 12:04
Show Gist options
  • Save renatoliveira/885caaf032740881af0ed922eb408623 to your computer and use it in GitHub Desktop.
Save renatoliveira/885caaf032740881af0ed922eb408623 to your computer and use it in GitHub Desktop.
SFSE #255489
<template>
<lightning-card title="Products" icon-name="custom:custom63">
<div class="slds-m-around_medium">
<template if:true={error}>
<p>{error}</p>
<p>{error.message}</p>
</template>
<template if:true={products}>
<lightning-datatable
key-field="Id"
data={products}
columns={columns}
is-loading={tableIsLoading}
hide-checkbox-column="true"
></lightning-datatable>
</template>
</div>
</lightning-card>
</template>
import { LightningElement, track, api } from 'lwc'
import getProducts from '@salesforce/apex/ComparisonTableController.getProducts'
import createAccount from '@salesforce/apex/ComparisonTableController.createAccount'
const columns = [
{ label: 'Name', fieldName: 'Product2.Name' },
{ label: 'Base price', fieldName: 'UnitPrice', type: 'currency' },
{ label: 'Product code', fieldName: 'Product2.ProductCode' }
]
export default class ComparisonTable extends LightningElement {
@track products
@track columns = columns
@track tableIsLoading = true
@track error
@api pricebookId
@api recordId
connectedCallback() {
getProducts({ pricebookId: this.pricebookId, countLimit: 4 })
.then(result => {
this.products = result.map(
record => Object.assign(
{
'Product2.Name': record.Product2.Name,
'Product2.ProductCode': record.Product2.ProductCode
},
record
)
)
this.tableIsLoading = false
})
.catch(error => {
this.error = error
})
createAccount().then(result => {
console.log('account created')
console.log(result)
}).catch(error => {
console.error('Account creation failed.')
console.error(JSON.stringify(error))
this.error = error.body.message
})
}
}
public class ComparisonTableController {
@AuraEnabled(cacheable=true)
public static List<PricebookEntry> getProducts (Id pricebookId, Integer countLimit) {
return [
SELECT
Id
,Product2.Name
,Product2.Family
,Product2.ProductCode
,Product2.IsActive
,Product2.QuantityUnitOfMeasure
,Product2.StockKeepingUnit
,UnitPrice
FROM PricebookEntry
WHERE Pricebook2Id = :pricebookId
LIMIT :countLimit
];
}
@AuraEnabled
public static Id createAccount () {
Account a = new Account();
try {
insert a;
} catch (Exception e) {
throw new AuraHandledException(e.getMessage());
}
return a.Id;
}
}
@renatoliveira
Copy link
Author

The controller class fails when the insert statement is executed by the platform. On the developer console log:

09:01:45:041 FATAL_ERROR System.LimitException: Too many DML statements: 1

The log ends with:

09:01:45:000 LIMIT_USAGE_FOR_NS   Number of DML statements: 1 out of 0 ******* CLOSE TO LIMIT

Which is really weird. I thought that the only thing that prevented a DML operation was marking the method as cacheable, as the documentation says in https://developer.salesforce.com/docs/component-library/documentation/lwc/apex.

@pranayjswl007
Copy link

So, As I can see, you are queuing 2 Apex Aura Enable call one to fetch getProducts and second to insert record in single apex call. There will be only one debug log saying both are same transaction

@pranayjswl007
Copy link

@renatoliveira .

According to this, a single governer limit is shared across multiple transactions. https://salesforce.stackexchange.com/a/192881/19118

So in your case when the transaction started the transaction was readOnly and when you do dml in same transaction you get the exception.

Fix would be to split it in 2 transctions, eg by calling createAccount(). in then block of getProducts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment