Problem
When executing custom JavaScript code in the CloudSense Solution Management Console (e.g., in a custom UIPlugin or event handler), an error occurs:
"TypeError: solution.getComponentByName is not a function"
Or similar errors such as:
- TypeError: Cannot read properties of undefined (reading 'getComponentByName')
- TypeError: Cannot read properties of undefined (reading 'getAttribute')
- TypeError: Cannot read properties of undefined (reading 'getConfiguration')
The error occurs when attempting to call methods on the solution object retrieved via CS.SM.getActiveSolution().
Cause
The error occurs when the CS.SM.getActiveSolution() method is called without using await. This method is asynchronous and returns a Promise, not the actual solution object.
If you do not use await (or .then()), the code proceeds immediately with an unresolved Promise instead of waiting for the actual solution data to be retrieved. When you then try to call methods like getComponentByName() on the Promise object (instead of the solution object), JavaScript throws an error because Promises do not have these methods.
Example Problematic Code
// INCORRECT: Missing await
var solution = CS.SM.getActiveSolution(); // Returns a Promise, not the solution
var component = solution.getComponentByName('MyComponent'); // ERROR: solution is a Promise, not a solution object
In this example, solution is a Promise object, not the actual solution. Calling solution.getComponentByName() fails because Promise objects do not have a getComponentByName method.
Resolution
Step 1: Add await Before the Asynchronous Call
Update your custom code to use await when calling CS.SM.getActiveSolution():
Before (Incorrect):
var solution = CS.SM.getActiveSolution();
var fibreComponent = solution.getComponentByName('FibreService');
var fibreConfiguration = fibreComponent.getConfiguration(connectivityService.value);
var voiceServiceBundle = fibreConfiguration.getAttribute('voiceServiceBundle').value;
After (Correct):
var solution = await CS.SM.getActiveSolution(); // Add await here
var fibreComponent = solution.getComponentByName('FibreService');
var fibreConfiguration = fibreComponent.getConfiguration(connectivityService.value);
var voiceServiceBundle = fibreConfiguration.getAttribute('voiceServiceBundle').value;
Step 2: Ensure the Function is Async
If you're using await, the containing function must be declared as async:
Before (Incorrect):
function myCustomFunction() {
var solution = await CS.SM.getActiveSolution(); // ERROR: await can only be used in async functions
// ...
}
After (Correct):
async function myCustomFunction() { // Add async keyword
var solution = await CS.SM.getActiveSolution();
// ...
}
Step 3: Alternative - Use .then() for Promise Handling
If you cannot use async/await (e.g., in older JavaScript environments), you can use .then() to handle the Promise:
CS.SM.getActiveSolution().then(function(solution) {
var fibreComponent = solution.getComponentByName('FibreService');
var fibreConfiguration = fibreComponent.getConfiguration(connectivityService.value);
var voiceServiceBundle = fibreConfiguration.getAttribute('voiceServiceBundle').value;
// ... rest of your logic
});
Step 4: Test the Fix
- Update your custom JavaScript code (e.g., in the Static Resource for your UIPlugin).
- Upload the updated Static Resource to Salesforce.
- Clear your browser cache or use an incognito window to test.
- Navigate to the Solution Management Console and trigger the custom logic.
- Verify that the error no longer occurs and that the solution object is correctly retrieved.
Prevention
- Code Review: When working with CloudSense Solution Management API methods, always check the API documentation to identify which methods are asynchronous (return Promises).
- Async/Await Best Practices: Use
async/awaitconsistently for all asynchronous operations to avoid Promise-related errors. - Testing: Test custom JavaScript code in a sandbox environment before deploying to production.
- Error Handling: Add try/catch blocks around
awaitcalls to handle potential errors gracefully:
async function myCustomFunction() {
try {
var solution = await CS.SM.getActiveSolution();
var component = solution.getComponentByName('MyComponent');
// ... rest of your logic
} catch (error) {
console.error('Error retrieving solution:', error);
CS.SM.displayMessage('An error occurred while retrieving the solution. Please contact support.', 'error');
}
}
Additional Notes
- The
CS.SM.getActiveSolution()method is asynchronous because it may need to fetch solution data from the server. - Other CloudSense Solution Management API methods that are asynchronous include:
CS.SM.refreshSolutionConsole()basket.performRemoteAction()component.updateConfigurationAttribute()- Always refer to the CloudSense API documentation for the specific release you are using to identify asynchronous methods.
- This issue is specific to custom JavaScript code. Out-of-the-box CloudSense UI does not exhibit this behavior.
Priyanka Bhotika
Comments