0

I have a visualforce component I am working on that simply has a table of data that is shown on a page layout within the service console. When you click on a link in the table, it opens a subtab using sforce.console.openSubtab.

I am trying to add a javascript function to track some usage so that when a subtab is opened, I can track some details.

My thought process here is when the openCaseSubTab function is called, the success callback triggers my custom trackUsage function which is a apex:actionFunction.


Component Example:

<apex:component id="externalTasksController" controller="TasksComponentController">
<script type="text/javascript">
        function openCaseSubTab(theCaseId, title) {
            sforce.console.getEnclosingPrimaryTabId(function (result) {
                sforce.console.openSubtab(result.id, '/' + theCaseId, true, title, null, openSuccess)
            });
        }
        var openSuccess = function openSuccess(result) {
            if (result.success) {
                trackUsage('Viewed External Task', 12345); // Testing with static ID
            }
        };
    </script>
    <apex:form>
        <apex:actionFunction name="trackUsage" action="{!trackUsage}" reRender="fakseresults">
            <apex:param name="val_action" value="" assignTo="{! trackedAction }" />
            <apex:param name="val_relatedRecordId" value="" assignTo="{! relatedRecordId }" />
        </apex:actionFunction>
    </apex:form>
</apex:component>

My controller:

public with sharing class TasksComponentController {
        public list<Task__x> tasks {get; set;}

        public String trackedAction {get; set;}
        public String relatedRecordId {get; set;}

        /**
         * Track Usage on Controller load
         */
        public void trackUsage() {
            Utilities.TrackUsage('Enterprise', 'Description', userInfo.getUserId(), this.trackedAction, this.relatedRecordId);
        }

    }

My Utilities:

public class Utilities {

    /**
     * Track usage
     */
    public static void TrackUsage(String destination, String source, String actorId, String action, String relatedRecord) {

        Cross_Org_Usage__c newTracking = new Cross_Org_Usage__c();
        newTracking.Destination_Org__c = destination;
        newTracking.Source_Org__c = source;
        newTracking.Actor_Id__c = actorId;
        newTracking.Action__c = action;
        newTracking.Related_Record_Id__c = relatedRecord;

        insert newTracking;

    }
}

The problem:

The tab briefly opens when I click on the link in the table and then I am shown: "URL No Longer Exists You have attempted to reach a URL that no longer exists on salesforce.com.". If I comment out the trackUseage function, the subtab opens fine so its happening when trying to run this function.

enter image description here

When this error is shown, the URL in the address bar is: https://xxxxx.my.salesforce.com/servlet/servlet.Integration?lid=0660x000000g4vO&ic=1&nonce=630a4f8a6203bc20cef92fa04abb3b22726576122848514f6ce4a97806884b83&sfdcIFrameOrigin=https%3A%2F%2Fxxxx.my.salesforce.com&isdtp=vw&linkToken=VmpFPSxNakF5TUMwd01TMHdPVlF4TkRveU16b3pNUzR4TXpCYSxTelNIOE53X21SYThXdHdNUjN5eVFhLFlXWmtNR0po&isWsVw=true

I am guessing that the form is submitting and refreshing the tab or causing some issue rather than just posting it to the APEX class. I added the reRender="fakseresults" in an attempt to solve this issue so that it didn't re-render the whole component and only tried to refresh the data in fakeresults, which doesn't really exist. Either way, with or without the re-render, I am experiencing this issue.

Any thoughts as to what is happening?


Update:

As a test, I commented out the subtab process so that as soon as a link is clicked, it would trigger this function without opening any tabs / subtabs. The same issue still occurs, so it appears to be a problem with the apex:function trying to send this data?

Update 2:

Debug logs on for this user are throwing the following:

DML currently not allowed

Class.Utilities.TrackUsage: line 48, column 1
Class.TasksComponentController.trackUsage: line 10, column 1
08:32:27.0 (126525532)|CODE_UNIT_FINISHED|VF: /apex/Tasks
08:32:27.0 (128533386)|EXECUTION_FINISHED

I looked into this and it's usually thrown if the constructor is trying to directly invoke a DML. In my case, it's in another method being triggered by an apex:function. Can I structure this differently to get around this DML error?

Update 3 - Solved?

I added allowDML="true" to my component and it seemed to resolve the issue. Not sure if this is going to cause me any other problems, but apparently it was due to the component not be able to trigger the DML? <apex:component id="externalTasksController" controller="TasksComponentController" allowDML="true">

  • 1
    Hi @SBB, if you've resolved this issue, please add your resolution as an answer and accept it. FWIW, you must specify allowDML on an Apex Component in order for DML to happen in its controller class. – nbrown Jan 6 at 15:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.