• Aaron Bailey 5
  • NEWBIE
  • 20 Points
  • Member since 2017
  • Senior Salesforce Developer
  • Purdue University Technical Assistance P


  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 2
    Questions
  • 9
    Replies
Background and Problem
I have an unlocked second-generation managed package containing some commonly-used apex across multiple orgs. I've added a new feature requiring configuration of one of the utils. I used Custom Metadata to accomplish this configuration (just two simple picklists). The Custom Metadata type (object with fields) and record (customMetadata) are both present in the VSCode project metadata. I've created a new package version (several...actually), but when I install it, the resulting package components do not contain the type.

More Details
  • This package is not intended to ever hit the App Exchange

Questions
  1. I'm aware of the existance of postInstallationScripts, but I'm not finding good documentation on how to make that happen, IF that is even what I need. Suggestions?
  2. If I'm on the right track with my build, what am I missing to make it work?
  3. Is there a better/preferred option for allowing admin configuration of a custom feature?
This is extremely odd to me, but likely has a simple explanation.

I have an object that acts as an Apex Log, for logging things in Apex, creatively called Apex_Log__c. It has two Long Text Area(32768) fields, Message__c and Exception__c. In a test method, I'm validating the custom save method handles oversized strings.

Test Method in ApexLoggerTest.cls
@IsTest
static void saveLongMessage() {
		
	// given
	ApexLogger logger = ApexLogger.create();

	// Build long string
	String shortString = 'ASDFGHJKLZXCVBN';
	String longString = '';
	while(longString.length() < 32768) {
		longString += shortString;
	}

	// Use the long string to test the limits
	Apex_Log__c log = new Apex_Log__c(
		Severity__c = longString,
		Class__c = longString,
		Method__c = longString,
		Message__c = longString,
		Exception__c = longString,
		WithException__c = false
	);
	system.assert(log.Message__c.length() > 32768);
	system.debug('mLen1: ' + log.Message__c.length());
	// DEBUG|mLen1: 32775

	// when
	Test.startTest();

	// Send to custom save method
	logger.save(log);

	Test.stopTest();

	// Info was logged
	List<Apex_Log__c> logs = getAllLogs();
	System.assertEquals(1, logs.size());
	Apex_Log__c thisLog = logs[0];

	// RETURNED MESSAGE IS THE WRONG LENGTH, SHOULD BE 32768
	System.debug('mLen4: ' + thisLog.Message__c.length());
	// DEBUG|mLen2: 32240

	// Logged data matches expected
	System.assert(thisLog.Name.contains(shortString));
	System.assert(thisLog.Name.contains('...'));
	System.assert(thisLog.Method__c.contains(shortString));
	System.assert(thisLog.Method__c.contains('...'));
	System.assert(thisLog.Class__c.contains(shortString));
	System.assert(thisLog.Class__c.contains('...'));
	System.assert(thisLog.Exception__c.contains(shortString));
	System.assert(thisLog.Exception__c.contains('...'));
	System.assert(thisLog.Message__c.contains(shortString));

	// THIS ASSERT IS FAILING DUE TO MISSING 528 CHARACTERS OFF THE RIGHT, THUS NO "..."
	System.assert(thisLog.Message__c.contains('...'));
}

Supporting method in ApexLoggerTest.cls
private static List<Apex_Log__c> getAllLogs() {
	return [
		SELECT Name, Time__c, Severity__c, Class__c, Method__c, Message__c, WithException__c, Exception__c, Timestamp__c
		FROM Apex_Log__c
          ORDER BY Timestamp__c DESC
	];
}

Custom save method in ApexLogger.cls
@TestVisible
private void save(Apex_Log__c log) {
	Datetime now = System.now();
	log.Timestamp__c = now;
	log.Time__c = now.format(TIMESTAMP_FORMAT);

	system.debug('mLen2: ' + log.Message__c.length());
	// DEBUG|mLen2: 32775

	// Set Name field
	if(String.isBlank(log.Name) && !String.isBlank(log.Message__c)) {
		log.Name = log.Message__c;
	}

	// Prevent string lengths beyond field size
	if(!String.isBlank(log.Name) && log.Name.length() > 80) {
		log.Name = log.Name.left(77) + '...';
	}
	if(!String.isBlank(log.Method__c) && log.Method__c.length() > 255) {
		log.Method__c = log.Method__c.left(252) + '...';
	}
	if(!String.isBlank(log.Class__c) && log.Class__c.length() > 255) {
		log.Class__c = log.Class__c.left(252) + '...';
	}
	if(!String.isBlank(log.Message__c) && log.Message__c.length() > 32768) {
		log.Message__c = log.Message__c.left(32765) + '...';
	}
	if(!String.isBlank(log.Exception__c) && log.Exception__c.length() > 32768) {
		log.Exception__c = log.Exception__c.left(32765) + '...';
	}
	if(!String.isBlank(log.Severity__c) && log.Severity__c.length() > 20) {
		log.Severity__c = log.Severity__c.left(17) + '...';
	}
	
	// Insert
	insert log;
	system.debug('mLen3: ' + log.Message__c.length());
	// DEBUG|mLen3: 32768
}

Snapshot of Apex_Log__c fields list
Snapshot of Apex_Log__c fields list

Message__c is somehow missing 528 characters, but there's nothing I can see that should be affecting the value asside from the trim. I've looked at this so many times, I'm going crosseyed. Any thoughts on why these two fields are behaving differently, despite using the exact same inputs/process?
This is extremely odd to me, but likely has a simple explanation.

I have an object that acts as an Apex Log, for logging things in Apex, creatively called Apex_Log__c. It has two Long Text Area(32768) fields, Message__c and Exception__c. In a test method, I'm validating the custom save method handles oversized strings.

Test Method in ApexLoggerTest.cls
@IsTest
static void saveLongMessage() {
		
	// given
	ApexLogger logger = ApexLogger.create();

	// Build long string
	String shortString = 'ASDFGHJKLZXCVBN';
	String longString = '';
	while(longString.length() < 32768) {
		longString += shortString;
	}

	// Use the long string to test the limits
	Apex_Log__c log = new Apex_Log__c(
		Severity__c = longString,
		Class__c = longString,
		Method__c = longString,
		Message__c = longString,
		Exception__c = longString,
		WithException__c = false
	);
	system.assert(log.Message__c.length() > 32768);
	system.debug('mLen1: ' + log.Message__c.length());
	// DEBUG|mLen1: 32775

	// when
	Test.startTest();

	// Send to custom save method
	logger.save(log);

	Test.stopTest();

	// Info was logged
	List<Apex_Log__c> logs = getAllLogs();
	System.assertEquals(1, logs.size());
	Apex_Log__c thisLog = logs[0];

	// RETURNED MESSAGE IS THE WRONG LENGTH, SHOULD BE 32768
	System.debug('mLen4: ' + thisLog.Message__c.length());
	// DEBUG|mLen2: 32240

	// Logged data matches expected
	System.assert(thisLog.Name.contains(shortString));
	System.assert(thisLog.Name.contains('...'));
	System.assert(thisLog.Method__c.contains(shortString));
	System.assert(thisLog.Method__c.contains('...'));
	System.assert(thisLog.Class__c.contains(shortString));
	System.assert(thisLog.Class__c.contains('...'));
	System.assert(thisLog.Exception__c.contains(shortString));
	System.assert(thisLog.Exception__c.contains('...'));
	System.assert(thisLog.Message__c.contains(shortString));

	// THIS ASSERT IS FAILING DUE TO MISSING 528 CHARACTERS OFF THE RIGHT, THUS NO "..."
	System.assert(thisLog.Message__c.contains('...'));
}

Supporting method in ApexLoggerTest.cls
private static List<Apex_Log__c> getAllLogs() {
	return [
		SELECT Name, Time__c, Severity__c, Class__c, Method__c, Message__c, WithException__c, Exception__c, Timestamp__c
		FROM Apex_Log__c
          ORDER BY Timestamp__c DESC
	];
}

Custom save method in ApexLogger.cls
@TestVisible
private void save(Apex_Log__c log) {
	Datetime now = System.now();
	log.Timestamp__c = now;
	log.Time__c = now.format(TIMESTAMP_FORMAT);

	system.debug('mLen2: ' + log.Message__c.length());
	// DEBUG|mLen2: 32775

	// Set Name field
	if(String.isBlank(log.Name) && !String.isBlank(log.Message__c)) {
		log.Name = log.Message__c;
	}

	// Prevent string lengths beyond field size
	if(!String.isBlank(log.Name) && log.Name.length() > 80) {
		log.Name = log.Name.left(77) + '...';
	}
	if(!String.isBlank(log.Method__c) && log.Method__c.length() > 255) {
		log.Method__c = log.Method__c.left(252) + '...';
	}
	if(!String.isBlank(log.Class__c) && log.Class__c.length() > 255) {
		log.Class__c = log.Class__c.left(252) + '...';
	}
	if(!String.isBlank(log.Message__c) && log.Message__c.length() > 32768) {
		log.Message__c = log.Message__c.left(32765) + '...';
	}
	if(!String.isBlank(log.Exception__c) && log.Exception__c.length() > 32768) {
		log.Exception__c = log.Exception__c.left(32765) + '...';
	}
	if(!String.isBlank(log.Severity__c) && log.Severity__c.length() > 20) {
		log.Severity__c = log.Severity__c.left(17) + '...';
	}
	
	// Insert
	insert log;
	system.debug('mLen3: ' + log.Message__c.length());
	// DEBUG|mLen3: 32768
}

Snapshot of Apex_Log__c fields list
Snapshot of Apex_Log__c fields list

Message__c is somehow missing 528 characters, but there's nothing I can see that should be affecting the value asside from the trim. I've looked at this so many times, I'm going crosseyed. Any thoughts on why these two fields are behaving differently, despite using the exact same inputs/process?
I am trying to use the afterRender event in a custom component (below is the component markup, js handler and the error I am seeing). I have taken out all the code in the handler but I still can't get around the error. I also don't know what parameter I should be setting for value in the component markup for the handler. The documentation around afterRender is pretty sparse so wanted to see if someone in the group could help. If I remove the afterRender handler, the component shows without error.
 
Thank you.
 
<!-- COMPONENT MARKUP -->
<aura:handler name="afterRender" action="{!c.afterRender}" value="{!this}"/>
 
//js controller afterRender
afterRender: function (component, helper) {
                       
        this.superAfterRender();           
       
    }

----- ERROR MESSAGE -----
Uncaught Error in $A.getCallback() [Unfortunately, there was a problem. Please try again. If the problem continues, get in touch with your administrator with the error ID shown here and any other related details.
Action failed: forceChatter:lightningComponent$controller$doInit [Cannot read property 'b' of undefined]]
  • March 02, 2017
  • Like
  • 0
I'm trying to enable spam filtering on a Web-to-Lead form using the Create a Web-to-Lead Form.

This was quite tricky to start with because the pop-up to add an API Key Pair disappears if you click away from it! I managed to manually enter the secret as it was impossible to copy and paste it. Then I made a typo and found it was impossible to edit the key, as the page for editing keys is broken. The only way was to delete the key and add it again through the disappearing pop-up. 

Now I've included the form in our site, but the recaptcha does nothing - if I ignore and click submit, the form submits to https://www.salesforce.com/servlet/servlet.WebToLead?encoding=UTF-8 anyway which is just a blank page. 

I know this is new functionality but it doesn't seem like it is working at all?
Hi All,

While I am checking my Visualforce execution time line, I saw this two event in the log which takes more time in Visualforce.
I want to know what exactly it is and which part of the controller code is resposible for this.

Attached the log for the reference
User-added image
I am implementing lightning design system and bootstrap at the same time in lightning component, But unable to get the desired UI in responsive mode. 
Can i use both in lightning component.
Hello,

I've been trying to put together an APEX code library for integrations between Salesforce and Cvent's SOAP API.  I'm having some problems with the SOAP envelope generated by one of the API calls.  It's specifying the wrong namespace at one of the element nodes causing Cvent to fail to deserialize the envelope correctly.

I've tried tweaking the auto-generated classes in APEX (playing around with the apex_schema_type_info and Ids_type_info) to get the correct namespace at the right spot, but so far have had no luck.

Here is the API call I'm trying to make:
//Create an array and store the ids in it
CventWebServiceschemas.IdArray idArray = new CventWebServiceschemas.IdArray();
idArray.Id = updatedResult.Id; //updatedResult is an array of IDs returned from a previous API call

//Make API call to retrieve events
CventWebServiceschemas.RetrieveResult retrieveResult = ws.Retrieve_x('Event' ,idArray);
System.debug('retrieveRes: ' + retrieveResult);

Here are the APEX relevant classes generated when reading in the WSDL:

public CventWebServiceschemas.RetrieveResult Retrieve_x(String ObjectType,CventWebServiceschemas.IdArray Ids) {
            CventWebService.Retrieve_element request_x = new CventWebService.Retrieve_element();
            request_x.ObjectType = ObjectType;
            request_x.Ids = Ids;
            CventWebService.RetrieveResponse_element response_x;
            Map<String, CventWebService.RetrieveResponse_element> response_map_x = new Map<String, CventWebService.RetrieveResponse_element>();
            response_map_x.put('response_x', response_x);
            WebServiceCallout.invoke(
              this,
              request_x,
              response_map_x,
              new String[]{endpoint_x,
              'http://api.cvent.com/2006-11/Retrieve',
              'http://api.cvent.com/2006-11',
              'Retrieve',
              'http://api.cvent.com/2006-11',
              'RetrieveResponse',
              'CventWebService.RetrieveResponse_element'}
            );
            response_x = response_map_x.get('response_x');
            return response_x.RetrieveResult;
        }


public class Retrieve_element {
        public String ObjectType;
        public CventWebServiceschemas.IdArray Ids;
        private String[] ObjectType_type_info = new String[]{'ObjectType','http://api.cvent.com/2006-11',null,'1','1','false'};
        private String[] Ids_type_info = new String[]{'Ids','http://schemas.cvent.com/api/2006-11',null,'0','1','false'};
        private String[] apex_schema_type_info = new String[]{'http://api.cvent.com/2006-11','true','false'};
        private String[] field_order_type_info = new String[]{'ObjectType','Ids'};
    }

public class IdArray {
        public String[] Id;
        private String[] Id_type_info = new String[]{'Id','http://schemas.cvent.com/api/2006-11',null,'0','-1','false'};
        private String[] apex_schema_type_info = new String[]{'http://schemas.cvent.com/api/2006-11','true','false'};
        private String[] field_order_type_info = new String[]{'Id'};
    }


public class RetrieveResponse_element {
        public CventWebServiceschemas.RetrieveResult RetrieveResult;
        private String[] RetrieveResult_type_info = new String[]{'RetrieveResult','http://schemas.cvent.com/api/2006-11',null,'0','1','false'};
        private String[] apex_schema_type_info = new String[]{'http://api.cvent.com/2006-11','true','false'};
        private String[] field_order_type_info = new String[]{'RetrieveResult'};
    }


The issue I'm having is with the namespace on the idArray in the SOAP envelope.  When I create the API call through C# or .Net WebService Studio, it creates an envelope in the expected format below with the https://schemas.cvent.com/api/2006-11 specified on the <Ids> element.

...
<soap:Body>
  <Retrieve xmlns="http://api.cvent.com/2006-11">
    <ObjectType>Event</ObjectType>
      <Ids xmlns="http://schemas.cvent.com/api/2006-11">
        <Id>7A71F7AC-2EDC-4462-8CF6-46E7CB7BD763</Id>
      </Ids>
  </Retrieve>
</soap:Body>
...

When I do a retrieve call using the APEX generated classes, it's creating the below envelope, which is failing to deserialize since the <Ids> element is inheriting the http://api.cvent.com/2006-11 namespace.

...
<env:Body>
  <Retrieve xmlns="http://api.cvent.com/2006-11">
      <ObjectType>Event</ObjectType>
      <Ids>
        <Id xmlns="http://schemas.cvent.com/api/2006-11">7A71F7AC-2EDC-4462-8CF6-46E7CB7BD763</Id>
      </Ids>
  </Retrieve>
</env:Body>
...

Please let me know if you need any more information (or the full generated APEX classes and full APEX code).  I would have provided both but didn't see any way to upload files.