Thursday, December 10, 2015

System.LimitException: DML currently not allowed

Whenever we trying to perform any DML operations at the time of initial page load we will be ending up with an error called System.LimitException: DML currently not allowed. In this post I am going to show how to produce the issue with simple example and workaround for the same issue.

1.Create simple page and class as shown below

VF Page Name : DeleteAllConts
 <apex:page controller="DeleteAllContCtrl">  
 </apex:page>  

Controller
1:  public class DeleteAllContCtrl  
2:  {  
3:   public DeleteAllContCtrl()  
4:   {  
5:    Id AccId = Apexpages.CurrentPage().getParameters().get('id');    
6:    Delete ([SELECT id FROM Contact WHERE AccountID=:AccId]);  
7:   }  
8:  }  

Now create a simple page with hyperlink and run it by passing any AccountID
1:  <apex:page standardController="Account">  
2:        <apex:outputLink value="/apex/DeleteAllConts?id={!Account.id}"> Delete All Contacts</apex:outputLink>   
3:  </apex:page>  

When user clicks on link it will be calling the DeleteAllConts page by passing the current AccountID as parameter.Once the execution starts at the controller it will be throwing an error System.LimitException: DML currently not allowed at delete statement(line number 6) in DeleteAllContCtrl class.

Reason for the Error:
1.When you are trying invoke any controller from visual force page to perform any dml operations (insert/delete/update/upsert) inside the constructor or any method called from constructor it will not allowed.
2.Within a single transaction - Web Service callouts just after the DML operation.(Thanks for Girish for providing this point)

Workaround for solutions 

1. Move the dml statements out of the constructor
2.Create a method place that dml operations inside that method and invoke that method directly from page using the action attribute in <apex:page> tag

Modified DeleteAllConts Page and Controller

 <apex:page controller="DeleteAllContCtrl" action="{!delContacts}">  
 </apex:page>  

1:  public class DeleteAllContCtrl  
2:  {  
3:   public DeleteAllContCtrl()  
4:   {  
5:    System.debug('Eneterd Inside Contsructor');  
6:   }  
7:   public void delContacts()  
8:   {  
9:    Id AccId = Apexpages.CurrentPage().getParameters().get('id');    
10:    Delete ([SELECT id FROM Contact WHERE AccountID=:AccId]);  
11:   }  
12:  }  

Thanks for visiting....Enjoy.....

Thursday, December 3, 2015

How to get salesforce base URL in visual force page at runtime

When we are writing any code related to Salesforce Instance URL it shouldn't be hard coded.The reason behind it when you deeply the the same code to other environments like sandboxes or production the base URL might be changed based on instances.At that point of time your code might breaks and it will stop working.

So whenever your dealing with any URL related stuff it's better to get the instance URL(BaseURL,any other parameters) at run time based on the instance.There are already so many ways that you can get the baseURL in apex but if you want to get it in vf page one way is as below

Getting salesforce instance URL in VF page

<script>
   var totalPageURL = window.location.toString();
   var protocalType= totalPageURL.split("//")[0];
   var tempbaseURL = totalPageURL.split("//")[1].split("/");
   var finalBaseURL = protocalType+'//'+tempbaseURL[0];
   alert(finalBaseURL );
</script>

Example:

Input
Lets take if your page url is like https://cs26.salesforce.com/800/o

Output
Then this will give output as https://cs26.salesforce.com (which is baseURL)

To test this snippet on any web page 

1. Just open any web page 
2. Press F12 (for chrome) or Right click open inspect element
3. Click on console 
4. Paste the code by removing <script> tag and press enter

Then you will popup with alert message which displays your BaseURL.

For more info please refer highlighted areas in below image 


























Thanks for visiting..Enjoy.....