• Daniel Watson 21
  • NEWBIE
  • 45 Points
  • Member since 2018

  • Chatter
    Feed
  • 0
    Best Answers
  • 2
    Likes Received
  • 0
    Likes Given
  • 6
    Questions
  • 11
    Replies
Hello Devs,

Is there a way to reset all the transiant test data in a unit test class. For instance you tested a few methods of a class, but to test the remaining methods you need/want to start with a clean slate. I want to purge all the fake data in the database.

I know if I keep track of the records I create, I can delete them at the end of a test, but that does not take care of records that are created via triggers, triggers that I am not testing for, and might not be thinking about during this unit.

Thanks!
I am not sure if this is a new change from v43.0 but I am unable to get my Apex to post to chatter.

I have an "Administrator" case RecordType and if it has children case, once and update is processed on the child case, a chatter post will be posted to the parent with an @menttion to the owner.

CODE:
if (Trigger.isUpdate) {
            if (newCase.ParentId != null) { 					// If case has a parent case
            	for (Case c : ParentAdminCases) { //<-- bulk soql'ed outside of trigger loop.
            		if(c.ParentId == newCase.ParentId) {		// If cases parent is of type admin.
            			ConnectApi.FeedItemInput feedItemInput = new ConnectApi.FeedItemInput();
						ConnectApi.MentionSegmentInput mentionSegmentInput = new ConnectApi.MentionSegmentInput();
						ConnectApi.MessageBodyInput messageBodyInput = new ConnectApi.MessageBodyInput();
						ConnectApi.TextSegmentInput textSegmentInput = new ConnectApi.TextSegmentInput();
						
						messageBodyInput.messageSegments = new List<ConnectApi.MessageSegmentInput>();
						
						mentionSegmentInput.id = newCase.Parent.OwnerId; // Set @mention
						messageBodyInput.messageSegments.add(mentionSegmentInput);
						
						textSegmentInput.text = 'Blah blah blah blha';
						messageBodyInput.messageSegments.add(textSegmentInput);
						
						feedItemInput.body = messageBodyInput;
						feedItemInput.feedElementType = ConnectApi.FeedElementType.FeedItem;
						feedItemInput.subjectId = newCase.ParentId; 
						
						ConnectApi.FeedElement feedElement = ConnectApi.ChatterFeeds.postFeedElement(Network.getNetworkId(), feedItemInput);
						
            			break;
            		}
            	}
            }
        }
My code compiles, but when I attempt to edit the child case I get the error in the description:
  • ConnectApi.ConnectApiException: Must have value for exactly one of the following: username, id
and am unbale to save the child record.

Other threads I have poured over seem to hint that it is a user permissions issue, but I am testing with the supper admin in a sandbox, so not sure what else I would need access to.

Seems like over the versions of the API there has been a varieance of signatures for the postFeedElement() method, so wondering if my issue is there.

Any advice would be much apreciated.

Thanks!
I have several Schedulable Apex classes that run monthly to build out some custom objects and cases for coming projects in coming months. There may however be instances where my company adds an account and need to run these jobs manually to quickly get the account on track, rather than waiting until the first of the next month for my jobs to do so.

I slapped together a lighting page component with some buttons that call to the controller methods that create an instance of the schedulable class and then calls:
[instance].execute(null);
When I click on the component buttons, sometimes I get a recursion error. Logging "response" to the console, I get like 1000 "SUCCESS" objects, but no new objects / cases are created in the database. I am concerned that this is just not how these classes should be called.

Is there a better way to accomplish what I am describing?

Thanks!

CODE:
MARKUP:
<aura:component controller="Controller_RunApex" implements="flexipage:availableForAllPageTypes" access="global">
    <lightning:card title="ApexRunner" class="container">
        <lightning:button variant="brand" label="ReconciliationsForAccounts" onclick="{!c.ReconciliationsForAccounts}" />
        <lightning:button variant="brand" label="CasesForReconciliations" onclick="{!c.CasesForReconciliations}" />
        <lightning:button variant="brand" label="CustomCasesMonthly 1st" onclick="{!c.CustomCasesMonthly}" />
        <lightning:button variant="brand" label="CustomCasesWeekly Fri" onclick="{!c.CustomCasesWeekly}" />
    </lightning:card>
</aura:component>
CONTROLLER:
({
    ReconciliationsForAccounts : function(component, event, helper) {
        helper.runFunction(component, helper, "c.ReconciliationsForAccounts");
    },
    
    CasesForReconciliations : function(component, event, helper) {
        helper.runFunction(component, helper, "c.CasesForReconciliations");
    },
    
    CustomCasesMonthly : function(component, event, helper) {
        helper.runFunction(component, helper, "c.CustomCasesMonthly");
    },
    
    CustomCasesWeekly : function(component, event, helper) {
        helper.runFunction(component, helper, "c.CustomCasesWeekly");
    }
})
HELPER:
({
    runFunction : function(component, helper, functionName) {
        var action = component.get(functionName);
        action.setCallback(this, function(response) {
            var state = response.getState();
            if (state === "SUCCESS") {
                console.log(response);
            }
            else {
                helper.consolelLogErrors(response.getError());
            }
        });
        $A.enqueueAction(action);
    },
    
    /**
     * Logs errors to the browser console log.
     * @param {String} errors: The errors to display.
     */
       consolelLogErrors : function(errors) {
        if (errors) {
            if (errors[0] && errors[0].message) {
                console.log("Error message: " + errors[0].message);
            }
        } else {
            console.log("Unknown error");
        }
    }
})
APEX:
public class Controller_RunApex {
    
    @AuraEnabled
    public static void ReconciliationsForAccounts() {
        Schedulable_ReconciliationsForAccounts rfa = new Schedulable_ReconciliationsForAccounts();
        rfa.execute(null);
    }
    
    @AuraEnabled
    public static void CasesForReconciliations() {
        Schedulable_CasesForReconciliations cfr = new Schedulable_CasesForReconciliations();
        cfr.execute(null);
    }
    
    @AuraEnabled
    public static void CustomCasesMonthly() {
        Schedulable_CustomCasesMonthly_1st ccm1 = new Schedulable_CustomCasesMonthly_1st();
        ccm1.execute(null);
    }
    
    @AuraEnabled
    public static void CustomCasesWeekly() {
        Schedulable_CustomCasesWeekly_Fri ccwf = new Schedulable_CustomCasesWeekly_Fri();
        ccwf.execute(null);
    }
}
All my schedulable classes are @ 100% coverage and are bulk-ifide. Can post their code as well on request.

THANKS ALL!

Hello Dev friends,

I have a Lightning:Datatable that is on a component in an aura:if set. The idea is that you can select a few things on the datatable, hit a "Save" button, and the items you selected will be displayed in the else section fo the aura:if set. Then you could hit a "Edit" button and the component will bring you back to the datatable with the items you that you already selected, pragmatically selected.

Component:

<aura:component controller="ReconciliationController" implements="flexipage:availableForRecordHome,force:hasRecordId" access="global">
	<!-- Attributes for the Component -->
    <aura:attribute name="recordId" type="Id" />
    <aura:attribute name="thisRecon" type="Reconciliation__c" />
    <aura:attribute name="editVList" type="Boolean" default="true" />
    
    <!-- Attributes for the Benefits Edit DataTable -->
    <aura:attribute name="tableCols" type="List" />
    <aura:attribute name="selectedRows" type="List" /> <!-- The rows to be displayed. -->
    <aura:attribute name="rowsSelected" type="List" /> <!-- The rows to be saved and displayed latter. -->
    
    <!-- Attributes for the Benefits Status List -->
    <aura:attribute name="benefits" type="Sobject[]" />
    
    <!-- Initializer -->
    <aura:handler name="init" action="{!c.doInit}" value="{!this}"/>
    
    <!-- Component -->
    <lightning:card title="Benefit Vendors" class="container" >
        <aura:if isTrue="{!v.editVList}">
            <lightning:datatable data="{!v.benefits}"
                                 columns="{!v.tableCols}"
                                 keyField="Id"
                                 selectedRows="{!v.selectedRows}"
                                 onrowselection="{!c.UpdateSelectedRows}" 
                             />
            <aura:set attribute="else">
                <aura:iteration items="{!v.benefits}" var="detail">
                        <div class="slds-grid" id="{! globalId + '-recordview-' + detail.Id }" style="padding-left: 20px; padding-top:5px; background-color: #ffe2e2">
                            <div class="slds-col slds-size_4-of-5">
                                <p>{!detail.vendorName}</p>
                            </div>
                            <div class="slds-col slds-size_1-of-5">
                                <lightning:input type="checkbox-button" checked="false" name="{!detail.Id}" onchange="{!c.CheckboxChangedEvent}" />
                            </div>
                        </div>
                </aura:iteration>
            </aura:set>
        </aura:if>
        <div style="padding-left: 20px; padding-top: 15px;">
            <lightning:button variant="brand" label="Save" onclick="{!c.EditVendorsListEvent}" />
        </div>
    </lightning:card>
</aura:component>

Currently flipping back and forth between the two datatable and iteration components clears out selectedRows. And if I try and set selectedRows, the datatable crashes and fials to load until I logout of my sandbox and then back in agian.

Controller:

({
    /** Client-side Controller **/
    doInit : function(component, event, helper) {
        helper.getThisReconciliation(component, helper);
        var cols = [
            {label: 'Vendor', fieldName: 'vendorName', type: 'text'},
            {label: 'Type', fieldName: 'recordName', type: 'text'},
            {label: 'Created', fieldName: 'created', type: 'Date'}
        ];
        component.set("v.tableCols", cols);
    },
    
    UpdateSelectedRows : function(component, event, helper) {
        var selectedRows = event.getParam('selectedRows');        
        var setRows = [];
        for (var i = 0; i < selectedRows.length; i++){
            setRows.push(selectedRows[i].Id);
        }
        console.log(setRows);
        component.set("v.rowsSelected", setRows); // <-- Crashed datatable if "v.selectedRows"
    },
    
    EditVendorsListEvent : function(component, event, helper) {
        var editVList = component.get("v.editVList");
        if (editVList == true) { // SAVE
            helper.updateReconciliationState(component);
            event.getSource().set('v.label','Edit');
            component.set("v.editVList", false);
        } else { // EDIT
            helper.editReconciliationState(component);
            event.getSource().set('v.label','Save');
			component.set("v.editVList", true);
			$A.get('e.force:refreshView').fire();            
        }
    }
})
Helpers:
({
    // DATA GETTERS AND SETTERS...
    
    updateReconciliationState : function(component) {
        var action = component.get("c.updateReconciliation");
        var reconciliation = component.get("v.thisRecon");
        var benefits = component.get("v.benefits");
        var rowsSelected = component.get('v.rowsSelected');
        var selectedRows = component.get('v.selectedRows');
        
        console.log("Reconciliation:");
        console.log(reconciliation);
        console.log("Benefits:");
        console.log(benefits);
        console.log("RowsSelected:");
        console.log(rowsSelected);
        console.log("SelectedRows:");
        console.log(selectedRows);
    },
    
    editReconciliationState : function(component) {
        var rowsSelected = component.get('v.rowsSelected');
        var selectedRows = component.get('v.selectedRows');
        
        console.log("RowsSelected:");
        console.log(rowsSelected);
        console.log("SelectedRows:");
        console.log(selectedRows);
        
        
        
        // component.set('v.selectedRows', rowsSelected); <-- causes datatable to crash...
    },
    
})

The purpose for v.rowsSelected and v.SelectedRows was me testing if my issue was coming from if you could not set SelectedRows directyl or not. Otherwise I will get rid of one.
 
Hello Devs,

I have a component that is going to be using a <lightning:datatable /> object I am attempting to set the cols with:
var cols = [
    {label: 'Vendor', fieldName: 'a02_Vendor__r.Name', type: 'text'},
    {label: 'Type', fieldName: 'RecordType.Name', type: 'text'},
    {label: 'Created', fieldName: 'CreatedDate', type: 'Date'}
];
component.set("v.tableCols", cols);
Where the a02_Vendor__r.Name is a related Account Name and the RecordType is the RecordType of the Object being returned by my controller.

When I console.log(response.getReturnValue()) from my call back function I do see that I am getting the apropreate and expected resluts from my controller, however my lighting datatabel IS displaying the CreatedDate field, but the two realted fields are empty. Can we not use related or nested objects in the datatable component? (that would be silly)...

Any help would be much apreciated!
Hello Devs!

I spent all yesterday trying to figure out why my QuickAction Apex code was not working in my new instance of Salesforce, only to find this thread here in the stack exchange. The source indicates that the QuickAction features do no apply to the "Salesforce Mobile and Lightning Experience Actions". So I guess what I am looking for is conformation that this is true, and when it might become supported, or if not true, how to emplement this in my EmailDefualtsLoader implements QuickActionDefaulsHandler {} for Lightning Exp Email action.

Thanks All!
Hello Devs!

I spent all yesterday trying to figure out why my QuickAction Apex code was not working in my new instance of Salesforce, only to find this thread here in the stack exchange. The source indicates that the QuickAction features do no apply to the "Salesforce Mobile and Lightning Experience Actions". So I guess what I am looking for is conformation that this is true, and when it might become supported, or if not true, how to emplement this in my EmailDefualtsLoader implements QuickActionDefaulsHandler {} for Lightning Exp Email action.

Thanks All!
I am not sure if this is a new change from v43.0 but I am unable to get my Apex to post to chatter.

I have an "Administrator" case RecordType and if it has children case, once and update is processed on the child case, a chatter post will be posted to the parent with an @menttion to the owner.

CODE:
if (Trigger.isUpdate) {
            if (newCase.ParentId != null) { 					// If case has a parent case
            	for (Case c : ParentAdminCases) { //<-- bulk soql'ed outside of trigger loop.
            		if(c.ParentId == newCase.ParentId) {		// If cases parent is of type admin.
            			ConnectApi.FeedItemInput feedItemInput = new ConnectApi.FeedItemInput();
						ConnectApi.MentionSegmentInput mentionSegmentInput = new ConnectApi.MentionSegmentInput();
						ConnectApi.MessageBodyInput messageBodyInput = new ConnectApi.MessageBodyInput();
						ConnectApi.TextSegmentInput textSegmentInput = new ConnectApi.TextSegmentInput();
						
						messageBodyInput.messageSegments = new List<ConnectApi.MessageSegmentInput>();
						
						mentionSegmentInput.id = newCase.Parent.OwnerId; // Set @mention
						messageBodyInput.messageSegments.add(mentionSegmentInput);
						
						textSegmentInput.text = 'Blah blah blah blha';
						messageBodyInput.messageSegments.add(textSegmentInput);
						
						feedItemInput.body = messageBodyInput;
						feedItemInput.feedElementType = ConnectApi.FeedElementType.FeedItem;
						feedItemInput.subjectId = newCase.ParentId; 
						
						ConnectApi.FeedElement feedElement = ConnectApi.ChatterFeeds.postFeedElement(Network.getNetworkId(), feedItemInput);
						
            			break;
            		}
            	}
            }
        }
My code compiles, but when I attempt to edit the child case I get the error in the description:
  • ConnectApi.ConnectApiException: Must have value for exactly one of the following: username, id
and am unbale to save the child record.

Other threads I have poured over seem to hint that it is a user permissions issue, but I am testing with the supper admin in a sandbox, so not sure what else I would need access to.

Seems like over the versions of the API there has been a varieance of signatures for the postFeedElement() method, so wondering if my issue is there.

Any advice would be much apreciated.

Thanks!

Hello Dev friends,

I have a Lightning:Datatable that is on a component in an aura:if set. The idea is that you can select a few things on the datatable, hit a "Save" button, and the items you selected will be displayed in the else section fo the aura:if set. Then you could hit a "Edit" button and the component will bring you back to the datatable with the items you that you already selected, pragmatically selected.

Component:

<aura:component controller="ReconciliationController" implements="flexipage:availableForRecordHome,force:hasRecordId" access="global">
	<!-- Attributes for the Component -->
    <aura:attribute name="recordId" type="Id" />
    <aura:attribute name="thisRecon" type="Reconciliation__c" />
    <aura:attribute name="editVList" type="Boolean" default="true" />
    
    <!-- Attributes for the Benefits Edit DataTable -->
    <aura:attribute name="tableCols" type="List" />
    <aura:attribute name="selectedRows" type="List" /> <!-- The rows to be displayed. -->
    <aura:attribute name="rowsSelected" type="List" /> <!-- The rows to be saved and displayed latter. -->
    
    <!-- Attributes for the Benefits Status List -->
    <aura:attribute name="benefits" type="Sobject[]" />
    
    <!-- Initializer -->
    <aura:handler name="init" action="{!c.doInit}" value="{!this}"/>
    
    <!-- Component -->
    <lightning:card title="Benefit Vendors" class="container" >
        <aura:if isTrue="{!v.editVList}">
            <lightning:datatable data="{!v.benefits}"
                                 columns="{!v.tableCols}"
                                 keyField="Id"
                                 selectedRows="{!v.selectedRows}"
                                 onrowselection="{!c.UpdateSelectedRows}" 
                             />
            <aura:set attribute="else">
                <aura:iteration items="{!v.benefits}" var="detail">
                        <div class="slds-grid" id="{! globalId + '-recordview-' + detail.Id }" style="padding-left: 20px; padding-top:5px; background-color: #ffe2e2">
                            <div class="slds-col slds-size_4-of-5">
                                <p>{!detail.vendorName}</p>
                            </div>
                            <div class="slds-col slds-size_1-of-5">
                                <lightning:input type="checkbox-button" checked="false" name="{!detail.Id}" onchange="{!c.CheckboxChangedEvent}" />
                            </div>
                        </div>
                </aura:iteration>
            </aura:set>
        </aura:if>
        <div style="padding-left: 20px; padding-top: 15px;">
            <lightning:button variant="brand" label="Save" onclick="{!c.EditVendorsListEvent}" />
        </div>
    </lightning:card>
</aura:component>

Currently flipping back and forth between the two datatable and iteration components clears out selectedRows. And if I try and set selectedRows, the datatable crashes and fials to load until I logout of my sandbox and then back in agian.

Controller:

({
    /** Client-side Controller **/
    doInit : function(component, event, helper) {
        helper.getThisReconciliation(component, helper);
        var cols = [
            {label: 'Vendor', fieldName: 'vendorName', type: 'text'},
            {label: 'Type', fieldName: 'recordName', type: 'text'},
            {label: 'Created', fieldName: 'created', type: 'Date'}
        ];
        component.set("v.tableCols", cols);
    },
    
    UpdateSelectedRows : function(component, event, helper) {
        var selectedRows = event.getParam('selectedRows');        
        var setRows = [];
        for (var i = 0; i < selectedRows.length; i++){
            setRows.push(selectedRows[i].Id);
        }
        console.log(setRows);
        component.set("v.rowsSelected", setRows); // <-- Crashed datatable if "v.selectedRows"
    },
    
    EditVendorsListEvent : function(component, event, helper) {
        var editVList = component.get("v.editVList");
        if (editVList == true) { // SAVE
            helper.updateReconciliationState(component);
            event.getSource().set('v.label','Edit');
            component.set("v.editVList", false);
        } else { // EDIT
            helper.editReconciliationState(component);
            event.getSource().set('v.label','Save');
			component.set("v.editVList", true);
			$A.get('e.force:refreshView').fire();            
        }
    }
})
Helpers:
({
    // DATA GETTERS AND SETTERS...
    
    updateReconciliationState : function(component) {
        var action = component.get("c.updateReconciliation");
        var reconciliation = component.get("v.thisRecon");
        var benefits = component.get("v.benefits");
        var rowsSelected = component.get('v.rowsSelected');
        var selectedRows = component.get('v.selectedRows');
        
        console.log("Reconciliation:");
        console.log(reconciliation);
        console.log("Benefits:");
        console.log(benefits);
        console.log("RowsSelected:");
        console.log(rowsSelected);
        console.log("SelectedRows:");
        console.log(selectedRows);
    },
    
    editReconciliationState : function(component) {
        var rowsSelected = component.get('v.rowsSelected');
        var selectedRows = component.get('v.selectedRows');
        
        console.log("RowsSelected:");
        console.log(rowsSelected);
        console.log("SelectedRows:");
        console.log(selectedRows);
        
        
        
        // component.set('v.selectedRows', rowsSelected); <-- causes datatable to crash...
    },
    
})

The purpose for v.rowsSelected and v.SelectedRows was me testing if my issue was coming from if you could not set SelectedRows directyl or not. Otherwise I will get rid of one.
 
Hello Devs,

I have a component that is going to be using a <lightning:datatable /> object I am attempting to set the cols with:
var cols = [
    {label: 'Vendor', fieldName: 'a02_Vendor__r.Name', type: 'text'},
    {label: 'Type', fieldName: 'RecordType.Name', type: 'text'},
    {label: 'Created', fieldName: 'CreatedDate', type: 'Date'}
];
component.set("v.tableCols", cols);
Where the a02_Vendor__r.Name is a related Account Name and the RecordType is the RecordType of the Object being returned by my controller.

When I console.log(response.getReturnValue()) from my call back function I do see that I am getting the apropreate and expected resluts from my controller, however my lighting datatabel IS displaying the CreatedDate field, but the two realted fields are empty. Can we not use related or nested objects in the datatable component? (that would be silly)...

Any help would be much apreciated!
Hello Devs!

I spent all yesterday trying to figure out why my QuickAction Apex code was not working in my new instance of Salesforce, only to find this thread here in the stack exchange. The source indicates that the QuickAction features do no apply to the "Salesforce Mobile and Lightning Experience Actions". So I guess what I am looking for is conformation that this is true, and when it might become supported, or if not true, how to emplement this in my EmailDefualtsLoader implements QuickActionDefaulsHandler {} for Lightning Exp Email action.

Thanks All!