How To Use Javascript Promise with Aura/Lightning Components

Javascript Promises has been around for a while but only got the chance to use it on a current project I am working on.

In analogy you make a promise and either you fulfill or break your promise.

In Javascript Promises context these translate to “resolve” meaning promise is fulfilled or “reject” which means promise was broken and can be caused by an error.

A good use case for in Lightning is handling responses from asynchronous operations in which you pass a callback function. Then that callback function can make another asynchronous operation. Keep on nesting and you can easily eventually end with what they sometimes call callback hell as your code can be hard to manage.

Let’s dive into a creating Javascript Promise

I defined this as a helper method. It calls an apex method and depending on response and getState I mapped it to either resolve or reject.

Here I assigned a variable to the returned Promise in the javascript controller. The helper returns one parameter which is the response which I can access on the .then statement.

Here we called the p variable followed by a .then and the special callback function for Aura which is $A.getCallback. You can then chain another promise by calling and returning that promise. The next then can accept a parameter from the previous promise.

With Promises, this is more readable than a nested callback and easier to manage.

I hope you find this basic tip useful. Hit the comments below if you have questions.

How To Use Map Object In Aura Lightning Component

By Salesforce documentation, you can define several collection types including a Map.

A Map collection allows you have a key/value pair where the key is unique. Declaring such is easy by adding the following

<aura:attribute type="Map" name="fooMap" />

But in your controller, if you try to do any Map functions such as keys(), set(key, value), values(), you get an error such as:

set is not a function 

or

values is not a function.

What is happening in Lightning is even if you declared it as Map it is treated as an Object. It took me a while to figure this out.

To get around this “limitation” I manually assigned a map in the controller and then I was able to do Map functions. You can do this either on init or before you use the component Map.

Hope you find this tip useful.

How To Replace Salesforce Metadata Before Deploying using Ant Scripts

My particular use case is for Salesforce ant deployment. I wanted to replace some metadata before I deploy to the target org which will allow me to automate the process. I can fetch metadata from my sandbox org and when it gets deployed to the target org like production the values will be updated.

You should have the latest ant-salesforce.jar as a requirement. You can grab the latest ant migration tool from here – https://help.salesforce.com/articleView?id=code_tools_ant_using.htm&type=5

My sample script entails having a conditional check before doing the replace a logic with Custom Labels. This is how my build XML looks.

Additional library you would need to perform the conditional check is ant-contrib.jar file. You can grab the latest library from here – http://ant-contrib.sourceforge.net/

If you try to run the script without the library you might end with the error below.

Fix Ant Build Error: Problem: failed to create task or type if

On the build.xml simply add the reference to the library.

If everything is in place, like the properties file has the right credentials, running the following command should deploy your code and replace the values as per your ant script.

ant -Denvironment=prod -buildfile build.xml deployMetadata

Source code available here – https://github.com/olopsman/salesforce-ant

How To Fix [Cannot read property ‘setParams’ of undefined] for Application Event in Aura Components

Component.cmp

    <aura:registerEvent name="CRMAppEvent" type="c:CRMAppEvent"/>

Controller.js

        var compEvent = $A.get("e.c:CRMAppEvent"); 
        compEvent.setParams({"type" : response})
        compEvent.fire();

If you have registered that this component will fire an event and still you get this odd error when setting parameters to your event.

This indicates that it cannot find the event and it is undefined.
To fix this you need to set your application event access to global

CRMAppEvent.evt

<aura:event type="APPLICATION" description="This is the generic Application Event" access="global">
    <aura:attribute name="type" type="String"/>
</aura:event>

How to Fix Salesforce Deployment Errors: InfoNot a valid enumeration for type

If your deployment strategy still evolves around ant deployment and not the new Salesforce CLI and you encounter this error on your deployment.

Failed to check the status for request ID=0Af0r00000ClbNgCAJ. Error: InfoNot a valid enumeration for type: class com.sforce.soap.metadata.DeployProblemType. Retrying…

While digging around, I found out this is a tool issue. Chances are your ant-salesforce jar library is outdated, you need to grab the latest salesforce-ant version from here

https://developer.salesforce.com/docs/atlas.en-us.daas.meta/daas/forcemigrationtool_install.htm

Update the library on your ant build path. Check your build.xml for the classPath if you are unsure of the path.

<taskdef resource="com/salesforce/antlib.xml" uri="antlib:com.salesforce">
        <classpath>
            <pathelement location="${basedir}/ant-salesforce.jar" />
        </classpath>
</taskdef>