<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Salesforce Archives - Michael Soriano</title>
	<atom:link href="https://michaelsoriano.com/category/salesforce/feed/" rel="self" type="application/rss+xml" />
	<link>https://michaelsoriano.com/category/salesforce/</link>
	<description>I turn code into captivating user experiences for the web</description>
	<lastBuildDate>Wed, 14 Feb 2024 19:02:33 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.7.4</generator>
	<item>
		<title>Simple CICD for Salesforce using SFDX and GitHub Actions</title>
		<link>https://michaelsoriano.com/simple-cicd-for-salesforce-using-sfdx-and-github-actions/</link>
					<comments>https://michaelsoriano.com/simple-cicd-for-salesforce-using-sfdx-and-github-actions/#respond</comments>
		
		<dc:creator><![CDATA[Michael Soriano]]></dc:creator>
		<pubDate>Sat, 16 Jul 2022 20:18:23 +0000</pubDate>
				<category><![CDATA[Salesforce]]></category>
		<guid isPermaLink="false">https://michaelsoriano.com/?p=7778</guid>

					<description><![CDATA[<p>I&#8217;ve been building Salesforce applications for some time now and we&#8217;re always faced with the same struggle when in comes to CICD. See, we write code locally in our machines. Then we use SFDX to push to our sandboxes &#8211; this is so we can see the changes, as well as other users test what [&#8230;]</p>
<p>The post <a href="https://michaelsoriano.com/simple-cicd-for-salesforce-using-sfdx-and-github-actions/">Simple CICD for Salesforce using SFDX and GitHub Actions</a> appeared first on <a href="https://michaelsoriano.com">Michael Soriano</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>I&#8217;ve been building Salesforce applications for some time now and we&#8217;re always faced with the same struggle when in comes to CICD. See, we write code locally in our machines. Then we use SFDX to push to our sandboxes &#8211; this is so we can see the changes, as well as other users test what we&#8217;ve built. We commit to Git for storing our code, branch and merge changes. With VSCode, and extensions &#8211; this is working fine and as intended. </p>



<p class="btn"><a href="https://github.com/michaelsoriano/sf-gh-actions-cicd">View in GitHub</a></p>



<p>TL;DR &#8211; if you want to just get to the solution, simply click button above. </p>



<h3 class="wp-block-heading">The Struggle </h3>



<p>The problem lies when we want to deploy our code to the upper environments like UAT and Production. We use a tool called Copado, which takes the code from a designated Sandbox and deploys it. <em>It doesn&#8217;t take it from the repository where we originally store our code</em>. </p>



<p>So the developers would have to go to the Copado UI &#8211; &#8220;<strong>re-select</strong>&#8221; the files that have been modified, choose the Test(s) to run &#8211; validate, get it approved and then it pushes it to the orgs. It&#8217;s a very slow process. In addition, when one thing fails, you get to start all over again. </p>



<p>This design aims to solve all of that. Note that this solution is based on <a href="https://www.salesforceben.com/build-your-own-ci-cd-pipeline-in-salesforce-using-github-actions/">Pablo Gonazales&#8217; solution</a> &#8211; with a few tweaks of my own. I&#8217;ve also simplified the model greatly &#8211; as you&#8217;ll see below.</p>



<h3 class="wp-block-heading">Modular Repos, 2 Branches</h3>



<p>This model is designed for repositories that are &#8220;<em>Project</em>&#8221; based. So each repository ONLY has the components needed for the application to work. We are NOT deploying all metadata inside an org. It is designed to be small, modular and deployable.  </p>



<p>You can trim down your project by selecting only your application&#8217;s files &#8211; by updating your <strong>package.xml</strong> in your local SFDX project. I recommend using this <a href="https://github.com/vignaesh01/sfdx-package-generator">extension</a> for VSCode. </p>



<p>In addition, we only really have 2 branches: 1) The &#8220;<em><strong>feature branch</strong></em>&#8221; &#8211; which is the bug fix or the feature the developer is currently working on, and 2) <em><strong>master</strong></em> &#8211; which is where all the changes are merged into. </p>



<figure class="wp-block-image size-full"><img fetchpriority="high" decoding="async" width="690" height="418" src="https://michaelsoriano.com/wp-content/uploads/2022/07/image-1.png" alt="overview of workflow" class="wp-image-7795" srcset="https://michaelsoriano.com/wp-content/uploads/2022/07/image-1.png 690w, https://michaelsoriano.com/wp-content/uploads/2022/07/image-1-300x182.png 300w" sizes="(max-width: 690px) 100vw, 690px" /></figure>



<p>So this is a way simplified version &#8211; compared to Pablo&#8217;s original solution. The steps for the workflow is as follows: </p>



<ol class="wp-block-list"><li><span style="text-decoration: underline;">Create a Feature branch from Master</span> &#8211; every time a bug or a feature is added, a developer copies master and works on their own branch. <em>All commits / pushes to this branch stays here (and their personal org) &#8211; which they deploy to using SFDX </em></li><li>When changes are good &#8211; they <span style="text-decoration: underline;">open a Pull Request to master</span>. This deploys to the orgs (including UAT)</li><li>When everything is tested &#8211; <span style="text-decoration: underline;">PR is closed (merged to master)</span>. This deploys the code to production</li></ol>



<p>Again, this is a simplified version. For a more robust workflow &#8211; I suggest using Pablo&#8217;s design.</p>



<h3 class="wp-block-heading">GitHub Actions is the glue</h3>



<p>As mentioned above, when we code locally &#8211; we continuously deploy to our sandboxes all day. This is made possible by SFDX. Now, how do we tie this process in with CICD? That&#8217;s where GitHub Actions come in. </p>



<p>It&#8217;s basically the thing that ties the two together. </p>



<pre class="wp-block-code"><code lang="yaml" class="language-yaml">name: Deploy to Production
on:
    pull_request:
      branches: [ master ]
      types:
        - closed
      paths:
        - 'force-app/**'
       
jobs:
    push-to-prod:
        runs-on: ubuntu-latest       
            - name: 'Put changed files into a dir'  
              run: | 
                  mkdir changed-sources
                  sfdx sgd:source:delta --to "HEAD" --from "HEAD^" ...
            - name: 'Deploying to production'
              run: sfdx force:source:deploy -p "changed-sources/force-app" ...
...</code></pre>



<p>As you can see from the sample code above, we&#8217;re running SFDX inside Github &#8211; as if it was running in our local machine. In addition, we can run npm, node and bash &#8211; for things like file manipulation etc.</p>



<h3 class="wp-block-heading"> Features</h3>



<p><strong>Only deploy the changed files</strong>. Just like in Pablo&#8217;s solution &#8211; we&#8217;re only deploying files that have been changed from master. This keeps the deployment small and fast. </p>



<p>We have the ability to select test classes, or if we leave the default &#8220;all&#8221; &#8211; it will <strong>automatically detect test classes in your repo</strong> and run them. This logic is inside a file called &#8220;<em>parseTests.js</em>&#8221; which just looks at all Apex classes that ends with &#8220;Test&#8221;.  </p>



<p><strong>Code Scanning</strong> &#8211; this part has been commented out in the <strong>push-to-orgs.yml</strong> &#8211; but I strongly suggest using it. This scans the code for best practices and vulnerabilities.</p>



<p><strong>All interactions are done in the repo</strong>. No need to use external tools like Jenkins or Copado. We&#8217;re using Pull Requests as the basis of whether it gets deployed to the orgs and production. </p>



<p><strong>Git is the source of truth</strong>. Unlike Copado &#8211; this solution keeps the truth in the Git repo.</p>



<h3 class="wp-block-heading">How to Use</h3>



<p>The repo contains a sample SFDX project. Simply clone and open in VSCode to edit. You will notice a <strong>package.xml</strong> file &#8211; which dictates the files that&#8217;s part of the project.</p>



<figure class="wp-block-image size-full"><img decoding="async" width="727" height="616" src="https://michaelsoriano.com/wp-content/uploads/2022/07/structure.png" alt="files in the project" class="wp-image-7803" srcset="https://michaelsoriano.com/wp-content/uploads/2022/07/structure.png 727w, https://michaelsoriano.com/wp-content/uploads/2022/07/structure-300x254.png 300w" sizes="(max-width: 727px) 100vw, 727px" /></figure>



<p>Also inside the <strong>.github/worfklows</strong> folder are 2 files: <em>push-to-orgs.yml</em> and <em>push-to-prod.yml</em>. These are the actions. This is how we tell GitHub what to do when specific actions are triggered. In our case, its when pull requests are opened, synchronized and closed on the master branch.</p>



<p>You&#8217;re going to deploy to 3 orgs in total. So you&#8217;ll need to create 3 Action Secrets inside your repo settings.</p>



<figure class="wp-block-image size-full"><img decoding="async" width="852" height="307" src="https://michaelsoriano.com/wp-content/uploads/2022/07/image-2.png" alt="" class="wp-image-7804" srcset="https://michaelsoriano.com/wp-content/uploads/2022/07/image-2.png 852w, https://michaelsoriano.com/wp-content/uploads/2022/07/image-2-300x108.png 300w, https://michaelsoriano.com/wp-content/uploads/2022/07/image-2-768x277.png 768w" sizes="(max-width: 852px) 100vw, 852px" /></figure>



<p>These correspond to the orgs that you want to deploy to. To create the <strong>auth url</strong> run the command below:</p>



<pre class="wp-block-code"><code lang="JavaScript" class="language-JavaScript">sfdx force:org:display -u &lt;ORGUSERNAME&gt; --verbose --json &gt; auth.json</code></pre>



<p>This will produce a file called <em>auth.json</em>. Inside it is the URL that you need to plug in the repository secrets. You have to do this per org that you want to deploy to.</p>



<p>Once all of the setup is complete, simply create a branch from master and check it out. Open an Apex Class and edit. Stage the file, commit and push. </p>



<p>Now &#8211; open a <em>Pull Request</em>. This will trigger the job <strong>push-to-orgs.yml</strong>. </p>



<figure class="wp-block-image size-full"><img decoding="async" width="629" height="507" src="https://michaelsoriano.com/wp-content/uploads/2022/07/image-3.png" alt="" class="wp-image-7811" srcset="https://michaelsoriano.com/wp-content/uploads/2022/07/image-3.png 629w, https://michaelsoriano.com/wp-content/uploads/2022/07/image-3-300x242.png 300w" sizes="(max-width: 629px) 100vw, 629px" /></figure>



<p>Note that you don&#8217;t have to select any files, or test classes (although that option is available). </p>



<p>Also, any changes to the existing feature branch will trigger this job. Basically as long as the Pull Request hasn&#8217;t been closed &#8211; you are able to sync your changes as well as deploy automatically. </p>



<p>Once all is good &#8211; you can simply close the PR and it will run <strong>push-to-prod.yml</strong> &#8211; which just pushes it to your production org. </p>
<p>The post <a href="https://michaelsoriano.com/simple-cicd-for-salesforce-using-sfdx-and-github-actions/">Simple CICD for Salesforce using SFDX and GitHub Actions</a> appeared first on <a href="https://michaelsoriano.com">Michael Soriano</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://michaelsoriano.com/simple-cicd-for-salesforce-using-sfdx-and-github-actions/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Environment Variables in Custom Metadata Types</title>
		<link>https://michaelsoriano.com/environment-variables-in-custom-metadata-types/</link>
					<comments>https://michaelsoriano.com/environment-variables-in-custom-metadata-types/#respond</comments>
		
		<dc:creator><![CDATA[Michael Soriano]]></dc:creator>
		<pubDate>Sat, 23 Apr 2022 18:35:54 +0000</pubDate>
				<category><![CDATA[Salesforce]]></category>
		<guid isPermaLink="false">https://michaelsoriano.com/?p=7580</guid>

					<description><![CDATA[<p>Developing custom solutions for Salesforce has some challenges. One of them is having Environment Variables for your application, that can be deployed from org to org without having to change them. We&#8217;ve been using Custom Metadata Types (CMT), but once it get to another environment such as production, we end up having to change it. [&#8230;]</p>
<p>The post <a href="https://michaelsoriano.com/environment-variables-in-custom-metadata-types/">Environment Variables in Custom Metadata Types</a> appeared first on <a href="https://michaelsoriano.com">Michael Soriano</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Developing custom solutions for Salesforce has some challenges. One of them is having Environment Variables for your application, that can be deployed from org to org without having to change them. We&#8217;ve been using Custom Metadata Types (CMT), but once it get to another environment such as production, we end up having to change it. This is basically hardcoding it &#8211; which is bad. </p>



<p>What I want is something like an .ini file, that has the environment (org) and key values like below: </p>



<pre class="wp-block-code"><code class="">[orgname1]

key1=val1
key2=val2
...

[orgname2]

key1=val3
key2=val4
...</code></pre>



<p>This basically can get deployed to any org, and it will just dynamically map to the right set of key values. </p>



<h3 class="wp-block-heading">Why not use Custom Settings?</h3>



<p>So custom settings are independent from org to org. This sounds like the perfect solution for our scenario. But I want something in 1 file &#8211; similar to .env files in Node. One that I can include in the SFDX project and get deployed. I believe deploying custom settings &#8211; will deploy the same records (unless you do something like below).</p>



<h3 class="wp-block-heading">Why not YAML or JSON? </h3>



<p>I found that INI format is easier for admins to edit. All they have to worry about is grouping by orgs (enclosed in brackets) and immediately following are key value pairs separated by a new line. Note that the format is <em>key=val</em>. </p>



<p>In addition, YAML and JSON requires additional rules such as spaces, tabs, curly braces and commas, and the CMT editor is hard to work with when it comes to formatting. Again, INI format is easier for admins.  </p>



<p>I also chose CMT &#8211; because its a bit more secure and flexible to work with. You can also use a static file (static resource) or an object. But I don&#8217;t want an important file just sitting in a pool of static resources, as well as waste a SOQL call for the later.</p>



<h3 class="wp-block-heading">Setup the Custom Metadata Type</h3>



<p>First step is to create the CMT. Click create a new custom metadata type, fill in the fields and hit &#8220;<strong>Save</strong>&#8220;. I chose the name &#8220;<strong>LS Setting</strong>&#8220;, so we can store other records in this CMT. </p>



<figure class="wp-block-image size-full border"><img decoding="async" width="616" height="505" src="https://michaelsoriano.com/wp-content/uploads/2022/04/image.png" alt="" class="wp-image-7581" srcset="https://michaelsoriano.com/wp-content/uploads/2022/04/image.png 616w, https://michaelsoriano.com/wp-content/uploads/2022/04/image-300x246.png 300w" sizes="(max-width: 616px) 100vw, 616px" /></figure>



<p>Now add a custom field. This will store the actual contents of our file. Click on &#8220;<strong>New Custom Field</strong>&#8221; and fill in the fields. Use a Text Area Long type for this field. I named ours &#8220;<strong>Value</strong>&#8220;.</p>



<figure class="wp-block-image size-full border"><img decoding="async" width="475" height="399" src="https://michaelsoriano.com/wp-content/uploads/2022/04/image-1.png" alt="" class="wp-image-7582" srcset="https://michaelsoriano.com/wp-content/uploads/2022/04/image-1.png 475w, https://michaelsoriano.com/wp-content/uploads/2022/04/image-1-300x252.png 300w" sizes="(max-width: 475px) 100vw, 475px" /></figure>



<p></p>



<p>Now let&#8217;s enter a record. Name it whatever makes sense to you &#8211; in our case, its &#8220;<strong>Environment Variables</strong>&#8221; and for the &#8220;Value&#8221; &#8211; add our INI content and click &#8220;Save&#8221;. </p>



<figure class="wp-block-image size-full border"><img decoding="async" width="535" height="452" src="https://michaelsoriano.com/wp-content/uploads/2022/04/image-2.png" alt="" class="wp-image-7584" srcset="https://michaelsoriano.com/wp-content/uploads/2022/04/image-2.png 535w, https://michaelsoriano.com/wp-content/uploads/2022/04/image-2-300x253.png 300w" sizes="(max-width: 535px) 100vw, 535px" /></figure>



<p></p>



<p>Simply replace the highlighted parts with your org names, enclosed in brackets. </p>



<h3 class="wp-block-heading">Parsing the Variables with Apex</h3>



<p>So this is the fun part. We have a file that we can deploy &#8211; we simply have to write the logic that looks in this file and get&#8217;s the correct value that we need. </p>



<p>First, I want two static methods that I can use in combination with each other, to produce the desired results: </p>



<pre class="wp-block-code"><code lang="java" class="language-java">//first method:
// can return a list of all key value pairs for the org
getEnvVars(null); 
// returns a list with just the string value for spec key passed
getEnvVars('key1'); 

// second method: 
// can be used to get just 1 value 
getEnvVar('key1', envVars);</code></pre>



<p> </p>



<p>The purpose of the second method <em>Class.getEnvVar(&#8216;key1&#8217;, envVars);</em> is so that we can use it in a class multiple times, without having to parse again and again. We can get the 2nd parameter by running the first method in the class constructor or something like that. </p>



<h3 class="wp-block-heading">The getEnvVars() method </h3>



<p>Let&#8217;s build the core of the parser here. So we need to go through each line of the file and put them in the necessary maps and lists. Let&#8217;s built the method shell and add the data structures:</p>



<pre class="wp-block-code"><code lang="java" class="language-java">public static List&lt;String&gt; getEnvVars(String key){
    List&lt;String&gt; result = new List&lt;String&gt;(); //final result
    Map&lt;String,List&lt;String&gt;&gt; rawMap = new Map&lt;String,List&lt;String&gt;&gt;(); //temp store
    List&lt;Integer&gt; envIndexes = new List&lt;Integer&gt;(); //indexes of our orgs
    List&lt;Integer&gt; nodeIndexes = new List&lt;Integer&gt;(); //indexes of key=values

    //logic here...



    return result;
}</code></pre>



<p></p>



<p>I guess it would also help to grab the CMT. Add this in our function: </p>



<pre class="wp-block-code"><code lang="java" class="language-java">List&lt;OTP_Setting__mdt&gt; settings = [SELECT Value__c FROM LS_Setting__mdt WHERE DeveloperName = 'Environment_Variables'];
String metaData = settings[0].Value__c; </code></pre>



<p></p>



<p>Then let&#8217;s do a split on metadata. Let&#8217;s also remove the duplicates and populate the <strong>envIndexes </strong>and <strong>nodeIndexes </strong>in one go. </p>



<pre class="wp-block-code"><code lang="java" class="language-java">List&lt;String&gt; rawList = new List&lt;String&gt;();
for(String str : metaData.split('\n')){ //REMOVES EMPTY LINES...
   if(String.isNotBlank(str)){
      rawList.add(str);
   }
}
Integer index = 0; 
for(String str : rawList){
  if(str.startsWith('[')){ //AN ENVIRONMENT
     envIndexes.add(index);
  }else if(str.contains('=')){ //A NODE KEY/VAL has to have an '='
     nodeIndexes.add(index);
  }
  index++;
}</code></pre>



<p></p>



<p>Now let&#8217;s go through our lists of environment and node indexes, and build the <strong>rawMap </strong>map. One thing to note here, we have 2 arrays of indexes, and a rawList of values. See below:</p>



<pre class="wp-block-code"><code lang="java" class="language-java">// rawList [node1,kv1,kv2,kv3,node2,kv4,kv5,kv6]
// envIndexes [0,4]
//             0 1
// nodeIndexes [1,2,3,5,6,7]
//              0 1 2 3 4 5 </code></pre>



<p></p>



<p>So rawList is flat, and we have the arrays of indexes, so we can get the values of each item in rawList according to the indexes. Also, we determine which org they belong to by doing a &lt; and &gt; comparison to the next environment index. </p>



<pre class="wp-block-code"><code lang="java" class="language-java">for(Integer y=0; y&lt;rawList.size();y++){
    for(Integer i=0; i&lt;envIndexes.size();i++){
        if(y == envIndexes[i]){
           List&lt;String&gt; nodes = new List&lt;String&gt;();
               for(Integer x=0; x&lt;nodeIndexes.size();x++){
                   if(i == envIndexes.size()-1){ //at the last envindex
                       if(nodeIndexes[x] &gt; envIndexes[i]){
                          nodes.add(rawList[nodeIndexes[x]]);
                       }
                   }else{ //not last index
                       if(nodeIndexes[x] &gt; envIndexes[i] &amp;&amp; nodeIndexes[x] &lt; envIndexes[i+1] ){
                          nodes.add(rawList[nodeIndexes[x]]);
                       }
                   }                            
                }       
     String env = rawList[envIndexes[i]];     
     env = env.replace('[','').replace(']','').toLowerCase().trim();
     rawMap.put(env,nodes);
     }
  }
}</code></pre>



<p></p>



<p>Finally, let&#8217;s build the result &#8211; depending on the environment, and if there is a key parameter or not</p>



<pre class="wp-block-code"><code lang="java" class="language-java">String curOrg = URL.getSalesforceBaseUrl().getHost(); 
List&lt;String&gt; envVars = rawMap.get(curOrg);

if(key == null){
   result = envVars;
}else{
   result.add(Class.getEnvVar(key,envVars)); //we haven't built this yet...
}      </code></pre>



<p></p>



<h3 class="wp-block-heading">The getEnvVar() method</h3>



<p>This one is a small method that we use above &#8211; but we can also call in our other classes. </p>



<pre class="wp-block-code"><code lang="java" class="language-java"> public static String getEnvVar(String key, List&lt;String&gt; envVars){
    String result = ''; 
    for(String ev : envVars){                 
       if(ev.startsWithIgnoreCase(key)){
          List&lt;String&gt; temp = ev.split('=');
          if(temp[1] != null){
             result = temp[1];
          }
        }                
      }
    return result;
 }</code></pre>



<p></p>



<p>Now we can use the two methods anywhere in our project where we need environment variables. </p>



<p>Don&#8217;t forget to include this in your SFDX project using VSCode, I recommend using <a href="https://marketplace.visualstudio.com/items?itemName=VignaeshRamA.sfdx-package-xml-generator">SFDX PackageXML generator</a> &#8211; so you can select the custom object (custom metadata type), custom field and the actual record that you&#8217;ve created. This makes it so that you can commit to your repo using GIT and deploy to any org of your choice. </p>



<h3 class="wp-block-heading">Improvements</h3>



<p>Of course this code can be improved drastically. One thing I can think of is having a &#8220;default&#8221; org fallback. This is so that you don&#8217;t have to replicate entire blocks of key=values for every org &#8211; especially if they share the same settings. Also maybe an &#8220;inherited&#8221; type of org, where you can do multiple orgs in separate lines that share the same settings. I&#8217;ll leave that up to you. </p>



<p>Feel free to check out the code in <a href="https://github.com/michaelsoriano/lwc-starter/blob/master/force-app/main/default/classes/LS_Utils.cls">Github</a>. </p>
<p>The post <a href="https://michaelsoriano.com/environment-variables-in-custom-metadata-types/">Environment Variables in Custom Metadata Types</a> appeared first on <a href="https://michaelsoriano.com">Michael Soriano</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://michaelsoriano.com/environment-variables-in-custom-metadata-types/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>A few Apex tips that I&#8217;ve picked up along the way</title>
		<link>https://michaelsoriano.com/apex-tips-picked-up-along-the-way/</link>
					<comments>https://michaelsoriano.com/apex-tips-picked-up-along-the-way/#respond</comments>
		
		<dc:creator><![CDATA[Michael Soriano]]></dc:creator>
		<pubDate>Sat, 14 Aug 2021 16:30:14 +0000</pubDate>
				<category><![CDATA[Salesforce]]></category>
		<guid isPermaLink="false">http://michaelsoriano.com/?p=7307</guid>

					<description><![CDATA[<p>Salesforce&#8217;s server side language is called Apex. Apex is a strongly typed, object-oriented language that many say looks like Java. The language is strongly tied to the database and other objects in Salesforce, as well as its front end counterpart &#8211; Lightning. As a side note, having written loosely typed languages all my life, Apex [&#8230;]</p>
<p>The post <a href="https://michaelsoriano.com/apex-tips-picked-up-along-the-way/">A few Apex tips that I&#8217;ve picked up along the way</a> appeared first on <a href="https://michaelsoriano.com">Michael Soriano</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Salesforce&#8217;s server side language is called <strong>Apex</strong>. Apex is a strongly typed, object-oriented language that many say looks like Java. The language is strongly tied to the database and other objects in Salesforce, as well as its front end counterpart &#8211; Lightning. </p>



<img decoding="async" width="760" height="463" src="https://michaelsoriano.com/wp-content/uploads/2021/08/sf-apex.png" alt="Apex in VSCode" class="wp-image-7403" srcset="https://michaelsoriano.com/wp-content/uploads/2021/08/sf-apex.png 760w, https://michaelsoriano.com/wp-content/uploads/2021/08/sf-apex-300x183.png 300w" sizes="(max-width: 760px) 100vw, 760px" />



<p>As a side note, having written loosely typed languages all my life, Apex was a bit of a learning curve. I was a bit annoyed on how everything has to be type declared. Now I&#8217;m realizing the true power of static typing. Writing code is (<em>almost</em>) always bug-free 😎. Re-factoring is also so much easier and worry free.</p>



<p>Below are some tips and tricks that can be useful. I know Apex is not a popular language, but the concepts are pretty universal.</p>



<h3 class="wp-block-heading">Parsing JSON strings</h3>



<p>Almost guarantee, you will have to parse JSON for your applications. May it be from an API or accepting as parameters to your methods. </p>



<p>The simplest JSON response is something like below: </p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">{
   key : val1,
   key2 : val2
}</code></pre>



<p>You can do something like this:</p>



<pre class="wp-block-code"><code lang="java" class="language-java">Map&lt;String,Object&gt;&nbsp;parsedResponse&nbsp;=&nbsp;(&nbsp;Map&lt;String,Object&gt;)&nbsp;JSON.deserializeUntyped(jsonstr);
System.debug(parsedResponse.get('key1')); //val1
System.debug(parsedResponse.get('key2')); //val2</code></pre>



<p>The examples above simply gets the <em>value </em>part of the converted object. To the the &#8220;key&#8221; part, you have to loop through the object properties using <em>.keyset()</em> &#8211; almost similar to for..in in JavaScript. </p>



<p>For an array of objects like below:</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">[
{
   key : val1,
   key2 : val2
},
{
   key : val3,
   key2 : val4
}
]</code></pre>



<p>It gets a little more involved:</p>



<pre class="wp-block-code"><code lang="java" class="language-java">List&lt;Object&gt; parsedResponse = (List&lt;Object&gt;) JSON.deserializeUntyped(response);
for (Object finalObj : parsedResponse) {
            Map&lt;String,Object&gt;&nbsp;tempObjMap&nbsp;=&nbsp;(Map&lt;String,Object&gt;)&nbsp;finalObj;
            System.debug(tempObjMap.get('key'))  //val1,val3 ;
            System.debug(tempObjMap.get('key2')) //val2,val4 ;
}</code></pre>



<p>If the JSON string goes beyond many levels, you have to nest your loop corresponding to the levels &#8211; but inner logic should be the same. It can get complicated especially if its a mix of arrays and objects.  </p>



<p>The key is using Apex&#8217;s JSON class. <strong>deserializeUntyped() </strong>converts the JSON string into a workable objects / list of objects.</p>



<h3 class="wp-block-heading">Sending Bulk Email</h3>



<p>So using the default <strong>sendEmail()</strong> from the Messaging class has some limitations. While its okay to send a few emails at a time, you can&#8217;t send them in bulk. I believe there&#8217;s a limit of 10 per execution. So doing sendEmail() in a loop of records &#8211; will stop at 10. (this limit can be inaccurate, but I know its pretty low). </p>



<p>Note that doing things in a loop such as sending emails, database commands is always a bad thing in Apex. There are many limits that you can hit &#8211; that you almost always have to do everything in bulk.</p>



<pre class="wp-block-code"><code lang="java" class="language-java">List&lt;String&gt;&nbsp;emailAddressList;&nbsp;
List&lt;String&gt;&nbsp;emailSubjectList;&nbsp;
List&lt;String&gt;&nbsp;emailBodyList;&nbsp;
List&lt;Messaging.SingleEmailMessage&gt;&nbsp;allEmails&nbsp;=&nbsp;new&nbsp;List&lt;Messaging.SingleEmailMessage&gt;();
for(Integer&nbsp;x&nbsp;=&nbsp;0;&nbsp;x&nbsp;&lt;&nbsp;total;&nbsp;x++){ //total, you convert to map of lists&lt;strings&gt;
    List&lt;String&gt;&nbsp;toAddress&nbsp;=&nbsp;new&nbsp;List&lt;String&gt;();//&nbsp;setToAddresses&nbsp;accept&nbsp;a&nbsp;List&nbsp;(array)
    toAddress.add(emailAddressList.get(x));
&nbsp;   String&nbsp;subject&nbsp;=&nbsp;emailSubjectList.get(x);
&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;msgBody&nbsp;=&nbsp;emailBodyList.get(x);
    Messaging.SingleEmailMessage&nbsp;mail&nbsp;=&nbsp;new&nbsp;Messaging.SingleEmailMessage();
    mail.setToAddresses(&nbsp;toAddress&nbsp;);&nbsp;//&nbsp;only&nbsp;takes&nbsp;a&nbsp;List&nbsp;(array)&nbsp;as&nbsp;noted&nbsp;above&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;mail.setSubject(subject);
    mail.setHtmlBody(msgBody);
    allEmails.add(mail);
}
List&lt;Messaging.Email&gt;&nbsp;allMails&nbsp;=&nbsp;new&nbsp;List&lt;Messaging.Email&gt;();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
for(&nbsp;Integer&nbsp;j&nbsp;=&nbsp;0;&nbsp;j&nbsp;&lt;&nbsp;allEmails.size();&nbsp;j++&nbsp;){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;allMails.add(theEmails.get(j));
}
Messaging.sendEmail(&nbsp;allMails&nbsp;);&nbsp;&nbsp;&nbsp;&nbsp;</code></pre>



<p> So the key above is we&#8217;re sending allMails &#8211; which is a list of single email messages in bulk. </p>



<h3 class="wp-block-heading">Select * Equivalent for querying Fields from Tables (Objects) </h3>



<p>So this one is a little different. It&#8217;s more of a <em>hack</em>, because in Salesforce, a <strong>SELECT *</strong> is not allowed when doing SQL (<em>actually called SOQL</em>). This is for performance reasons I believe. It&#8217;s fair to think that programmers will lazily just keep using it instead of explicitly listing out the fields. </p>



<p>As a result, it becomes a bit tedious to maintain your select statements, when new fields are added to the table.</p>



<pre class="wp-block-code"><code lang="java" class="language-java">Set&lt;String&gt;&nbsp;fields = MyObject.getSobjectType().getDescribe().fields.getMap().keySet();
String&nbsp;qry&nbsp;=&nbsp;'SELECT&nbsp;';&nbsp;
Integer&nbsp;i&nbsp;=&nbsp;1;
String&nbsp;sep&nbsp;=&nbsp;',&nbsp;';
for(String&nbsp;field&nbsp;:&nbsp;fields){
&nbsp;&nbsp;&nbsp;&nbsp;sep&nbsp;=&nbsp;i&nbsp;==&nbsp;fields.size()&nbsp;?&nbsp;'&nbsp;'&nbsp;:&nbsp;sep;
&nbsp;&nbsp;&nbsp;&nbsp;qry&nbsp;+=&nbsp;field&nbsp;+sep;
&nbsp;&nbsp;&nbsp;&nbsp;i++;
}
qry&nbsp;+=&nbsp;'FROM&nbsp;MyObject';
Database.query(qry);&nbsp;&nbsp;&nbsp;&nbsp;</code></pre>



<p> You can optionally query just the custom fields &#8211; by simply checking if field name ends with &#8220;__c&#8221;. You can use the nifty <em>endsWithIgnoreCase()</em> for that. </p>



<h3 class="wp-block-heading">Debugging by Email</h3>



<p>Logging to the developer console in the browser can be limited. Especially if you&#8217;re trying to view large datasets. The console will chop of the responses and add an elipsis &#8220;&#8230;&#8221; when they reach a specific size. Besides, running code locally, then going to the browser and looking at logs was never a good experience for me. </p>



<p>Sending yourself logs via email is still slow, but gets the job done. Long strings are shown in full, and you have full control of what you want to see. </p>



<pre class="wp-block-code"><code lang="java" class="language-java">public&nbsp;static&nbsp;void&nbsp;emailErrorLog(List&lt;String&gt;&nbsp;errorLog){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;body&nbsp;=&nbsp;'';
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(string&nbsp;msg&nbsp;:&nbsp;errorLog){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;body&nbsp;+=&nbsp;'\n\n'&nbsp;+&nbsp;'&nbsp;--&nbsp;'&nbsp;+&nbsp;msg;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Messaging.SingleEmailMessage&nbsp;mail&nbsp;=&nbsp;new&nbsp;Messaging.SingleEmailMessage();&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mail.setToAddresses(new&nbsp;List&lt;String&gt;{'youremail@example.com'});
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mail.setSubject('Error Log');
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mail.setPlainTextBody(body);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Messaging.sendEmail(new&nbsp;Messaging.SingleEmailMessage[]&nbsp;{&nbsp;mail&nbsp;});&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
}
//to use:
List&lt;String&gt; debugLog = new List&lt;String&gt;();
debugLog.add('some line&nbsp;-&gt;&nbsp;'&nbsp;+&nbsp;JSON.serialize(someObject));
emailErrorLog(debugLog);</code></pre>



<p>Notice that we&#8217;re sending the message via <strong>setPlainTextBody()</strong> &#8211; just incase HTML gets inserted &#8211; and we don&#8217;t want that. Also, for objects, make sure you convert them all to strings by using <strong>JSON.serialize()</strong>.</p>



<h3 class="wp-block-heading">Get JSON from Static Resource</h3>



<p>So sometimes you just want to get mock data from a flat file. Maybe you don&#8217;t want to store it in a table just yet. Or maybe you&#8217;re just quickly doing a prototype. This technique grabs the contents of a static resource through Apex, and optionally return it to the front end. </p>



<pre class="wp-block-code"><code lang="java" class="language-java">@AuraEnabled
    public static String getItems(){
        StaticResource sr = [SELECT Id, Name, SystemModStamp, Body FROM StaticResource  WHERE Name = 'mockdata' LIMIT 1];      
        return sr.Body.toString();
    }  </code></pre>



<p>Then from your JavaScript, you simply call your method via <em>@import</em> &#8211; and you <a href="https://michaelsoriano.com/salesforces-lwc-lightning-web-components/#apexmethodpromise" data-type="URL" data-id="https://michaelsoriano.com/salesforces-lwc-lightning-web-components/#apexmethodpromise">use it as a Promise</a>. </p>



<p>Note that above is assumes that your filename is <strong>mockdata.json</strong>. </p>



<h3 class="wp-block-heading">SFDX Execute anonymous locally</h3>



<p>Okay so this one isn&#8217;t really Apex, but SFDX &#8211; which is the command line interface for Salesforce development. Again, this is a result of the same downsides  of working with the browser developer console. It takes too many clicks where you open the console, look for &#8220;Execute Anonymous&#8221; and a window pops up then &#8220;Execute&#8221;. </p>



<p>In VSCode, assuming you&#8217;re connected to your org, you can simply highlight the Apex code you want to run &#8211; and CTRL+Shift+P, and choose:</p>



<p><strong>SFDX Execute Anonymous with Highlighted Text</strong></p>



<p>This will run the code against your org, and show the results locally &#8211; in the Output tab.</p>
<p>The post <a href="https://michaelsoriano.com/apex-tips-picked-up-along-the-way/">A few Apex tips that I&#8217;ve picked up along the way</a> appeared first on <a href="https://michaelsoriano.com">Michael Soriano</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://michaelsoriano.com/apex-tips-picked-up-along-the-way/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Salesforce&#8217;s LWC (Lightning Web Components) &#8211; My First Thoughts</title>
		<link>https://michaelsoriano.com/salesforces-lwc-lightning-web-components/</link>
					<comments>https://michaelsoriano.com/salesforces-lwc-lightning-web-components/#comments</comments>
		
		<dc:creator><![CDATA[Michael Soriano]]></dc:creator>
		<pubDate>Mon, 28 Sep 2020 04:41:08 +0000</pubDate>
				<category><![CDATA[Salesforce]]></category>
		<category><![CDATA[LWC]]></category>
		<guid isPermaLink="false">http://michaelsoriano.com/?p=7239</guid>

					<description><![CDATA[<p>Oh no, another JavaScript framework to learn. At first, it sounds bad. But its a good thing actually. Because being stagnant in coding is bad. Always learning new things is the way to go. Besides, newer frameworks (especially in JavaScript) show what older frameworks could&#8217;ve done better. This is the case with Lightning Web Components [&#8230;]</p>
<p>The post <a href="https://michaelsoriano.com/salesforces-lwc-lightning-web-components/">Salesforce&#8217;s LWC (Lightning Web Components) &#8211; My First Thoughts</a> appeared first on <a href="https://michaelsoriano.com">Michael Soriano</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Oh no, another JavaScript framework to learn. At first, it sounds bad. But its a good thing actually. Because being stagnant in coding is bad. Always learning new things is the way to go. </p>



<p>Besides, newer frameworks  (<em>especially in JavaScript</em>) show what older frameworks could&#8217;ve done better. This is the case with Lightning Web Components (LWC). </p>



<figure class="wp-block-image size-large"><img decoding="async" width="1366" height="1015" src="https://michaelsoriano.com/wp-content/uploads/2020/09/undraw_code_review_l1q9.png" alt="Man with Code Background " class="wp-image-7263" srcset="https://michaelsoriano.com/wp-content/uploads/2020/09/undraw_code_review_l1q9.png 1366w, https://michaelsoriano.com/wp-content/uploads/2020/09/undraw_code_review_l1q9-300x223.png 300w, https://michaelsoriano.com/wp-content/uploads/2020/09/undraw_code_review_l1q9-1024x761.png 1024w, https://michaelsoriano.com/wp-content/uploads/2020/09/undraw_code_review_l1q9-768x571.png 768w" sizes="(max-width: 1366px) 100vw, 1366px" /></figure>



<p>LWC is Salesforce&#8217;s newest iteration of Lightning called <a href="https://michaelsoriano.com/tag/aura/" data-type="URL" data-id="https://michaelsoriano.com/tag/aura/">Aura</a>. Actually, iteration is an understatement. It&#8217;s more like an overhaul. See, Aura is a pretty old framework &#8211; I would say at least a decade old. And its the way I learned how to code Salesforce apps. As newer JS frameworks come up, Salesforce decides to up their game. </p>



<p>Enter Lightning Web Components, <strong>LWC </strong>for short.</p>



<p>I started using LWC for a couple of small components, and I&#8217;m liking it a lot. LWC uses web standards and less boilerplate. Just JavaScript, CSS and HTML. </p>



<h3 class="wp-block-heading">Import / Export</h3>



<p>This is probably the biggest change. You can now write modules &#8211; just how JS intended it to be. </p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">//importing modules into your component:
import { foo , bar } from "/path/to/lwc-component";
//exporting from your component
export { func1, func2}
//or you can export the entire file
export default class MyClass { .... </code></pre>



<p>No more clunky adding components in the HTML so you can access the helpers. Or extending components, or including static resources &#8211; like how its done with Aura. </p>



<p>This is a big change and I&#8217;m really enjoying it. </p>



<h3 class="wp-block-heading">Component Communication</h3>



<p>I happen to like the two way data-binding that existed in Aura. But the new way of passing data between components is not that bad. After a few uses, it&#8217;s actually quite neat. </p>



<p><strong><span style="text-decoration: underline;">Parent to child</span></strong> is straightforward. Just like other frameworks &#8211; using &#8220;props&#8221; or component attributes.   </p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">//parent html:
&lt;c-child some-data={someData}&gt;&lt;/c-child&gt;
//access it inside the child
export default class Child extends LightningElement {
   @api someData
...
// marking a property with @api makes it public - and writeable
// now each time parent changes someData - child changes as well</code></pre>



<p>Keep in mind binding is now uni-directional (from Top to Bottom). When we need to pass data upwards, we pass events. </p>



<p>Oh, to fire a child component&#8217;s method from the parent, you can simply do something like :</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">this.template.querySelector("c-child").someEventInChild()</code></pre>



<p>Make sure you make the method public by putting the &#8220;@api&#8221; on it.</p>



<p><strong><span style="text-decoration: underline;">Child to Parent</span></strong> is a little bit different than the example above. We still use attributes, but the attributes are actually custom events that fire.  </p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">//inside child JS
sendEmail () {
        const params = {somedata : "hello there..."};
        const evt = new CustomEvent("sendemail", {detail: params });
        this.dispatchEvent(evt);
    }
//note the custom event "sendemail"</code></pre>



<p>The parent component will use the custom event that is dispatched from the child, but will only find it by prefixing an &#8220;on&#8221; with the event name: </p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">//inside parent HTML:
&lt;c-child onsendemail={sendSingleEmail}
&gt;&lt;/c-child&gt;</code></pre>



<p>Now you have access to the parameters sent (inside the &#8220;detail&#8221; property) of the parent function &#8220;<em>sendSingleEmail</em>&#8220;:</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">sendSingleEmail(event){
      console.log(JSON.stringify(event.detail) // here is our stuff..
}</code></pre>



<p>Now, what about if the components are siblings? It would be cumbersome to use the techniques above just correct? And it doesn&#8217;t sound right if we have to reorder our components &#8211; just to avoid component sibling communication. </p>



<p><strong><span style="text-decoration: underline;">Sibling Components</span></strong> &#8211; use <em>Lightning Message Service.</em> </p>



<p>This is a component itself used for &#8220;publishing&#8221; and &#8220;subscribing&#8221; to data. This will solve our issue with sibling communication. I will not go through the process of how to use this service, you can read about that <a href="https://developer.salesforce.com/docs/component-library/bundle/lightning-message-service/documentation">here</a>: </p>



<p>Then in one component (where you want to receive data), you should be able to do something like below: </p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">subscribe(this.messageContext, YourChannelName, (message) =&gt; {
    this.items = message.items;
});</code></pre>



<p>That callback method in the end with the &#8220;message&#8221; parameter &#8211; can be used for all of your data manipulation in your current component. </p>



<p>Then in the other component, where the data is coming from, you do a &#8220;<em>publish</em>&#8220;.</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">publish(this.messageContext, YourChannelName, {items : this.items}); </code></pre>



<p>Pretty simple right? Of course there is quite a bit that I&#8217;m leaving out &#8211; but that&#8217;s up to you to dig up 😁</p>



<p>Overall, component communication is definitely harder than Aura. It does however remind me a little bit of <a href="https://michaelsoriano.com/redux-a-quick-and-high-level-overview/" data-type="URL" data-id="https://michaelsoriano.com/redux-a-quick-and-high-level-overview/">Redux</a>. </p>



<h3 class="wp-block-heading" id="apexmethodpromise">Apex Methods are JavaScript Promises</h3>



<p>This one is Salesforce specific &#8211; but is still quite nice. Now you can use the &#8220;import&#8221; statement, for an aura enabled method in your Apex class. An aura enabled method is one that you can call from your front end component. </p>



<p>And if you&#8217;re sill lost &#8211; Apex is Salesforce&#8217;s server side language, while JavaScript Promises are well.. here&#8217;s an <a href="https://michaelsoriano.com/working-with-jquerys-ajax-promises-and-deferred-objects/">old article</a> of what they are.</p>



<p>So you can do something like: </p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">import getRecord from '@salesforce/apex/YourClass.getRecord';
//then you can use it like below:
let params = {recordid : id};
getRecord(params).then((result)=&gt;{
    //process result...
}).catch((er)=&gt;{
    //process error
})</code></pre>



<p>The imported method from Apex becomes a JS promise &#8211; where you can handle it like regular JavaScript. You no longer have to muck with &#8220;<em><a href="https://michaelsoriano.com/call-apex-from-lightning-components/" data-type="URL" data-id="https://michaelsoriano.com/call-apex-from-lightning-components/">$A.enqueueAction(action)</a></em>&#8221; like before.</p>



<p>The only thing I don&#8217;t like is when you want to use multiple methods &#8211; you have to import them one at a time. I&#8217;m not sure if you can import all aura methods of a class. Maybe in future releases.</p>



<h3 class="wp-block-heading">Templates</h3>



<p>Not a Templating language like Liquid or Handlebars, just the template tag in HTML. Yes &#8211; LWC is composed of all template tags for logic in HTML. </p>



<p>I wouldn&#8217;t say it&#8217;s the most elegant code, but I&#8217;m getting used to it. Seeing something like: </p>



<pre class="wp-block-code"><code lang="markup" class="language-markup"> &lt;template if:true={hasError}&gt;
     &lt;h3&gt;There's an error&lt;/h3&gt;
 &lt;/template&gt;
&lt;template if:false={hasError}&gt;
     //continue application code
&lt;/template&gt; </code></pre>



<p>It just feels a little weird. But this is not Salesfoce&#8217;s fault. This is web standards and that&#8217;s the way it has to be. </p>



<p>And that&#8217;s about it so far. Like I said, I am enjoying using LWC and learning it at the same time. </p>



<p>I do wish that Salesforce provide better docs. Most of the time I search for something &#8211; and it leads to a Github repo. And we&#8217;re just supposed to dig through the code to find an answer. </p>



<p>Its your turn. </p>



<p>Have you tried LWC? What do you think? Leave your comments below. </p>
<p>The post <a href="https://michaelsoriano.com/salesforces-lwc-lightning-web-components/">Salesforce&#8217;s LWC (Lightning Web Components) &#8211; My First Thoughts</a> appeared first on <a href="https://michaelsoriano.com">Michael Soriano</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://michaelsoriano.com/salesforces-lwc-lightning-web-components/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>How to create simple Pagination using Lightning components and Apex</title>
		<link>https://michaelsoriano.com/how-to-create-simple-pagination-using-lightning-components-and-apex/</link>
					<comments>https://michaelsoriano.com/how-to-create-simple-pagination-using-lightning-components-and-apex/#comments</comments>
		
		<dc:creator><![CDATA[Michael Soriano]]></dc:creator>
		<pubDate>Wed, 17 Apr 2019 21:37:17 +0000</pubDate>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Salesforce]]></category>
		<category><![CDATA[Aura]]></category>
		<guid isPermaLink="false">http://michaelsoriano.com/?p=6850</guid>

					<description><![CDATA[<p>Let&#8217;s build something every web application needs in their results page: Pagination (aka Paging). This technique is necessary so we don&#8217;t bombard our users with all the items in our result page. Instead, we show them in &#8220;chunks&#8221; or &#8220;sets&#8221; of results. This is a very simplistic example &#8211; all we&#8217;re doing is a set [&#8230;]</p>
<p>The post <a href="https://michaelsoriano.com/how-to-create-simple-pagination-using-lightning-components-and-apex/">How to create simple Pagination using Lightning components and Apex</a> appeared first on <a href="https://michaelsoriano.com">Michael Soriano</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Let&#8217;s build something every web application needs in their results page: <strong>Pagination</strong> (aka Paging). This technique is necessary so we don&#8217;t bombard our users with all the items in our result page. Instead, we show them in &#8220;chunks&#8221; or &#8220;sets&#8221; of results. This is a very simplistic example &#8211; all we&#8217;re doing is a set of buttons that have page numbers on them. Once clicked, it will go ahead and fetch the results in that page. </p>



<p>A peak at what we&#8217;re building is shown below:</p>



<p>Disclaimer: I&#8217;m assuming you know how to work with Lightning components. I also hope you know JavaScript and HTML. There&#8217;s no downloadable code &#8211; you just simply have to follow along.</p>



<figure class="wp-block-image border"><img decoding="async" width="644" height="363" src="https://michaelsoriano.com/wp-content/uploads/2019/03/paging-lightning.gif" alt="Lightning Pagination" class="wp-image-6852"/></figure>



<p>Currently, there are no built in lightning component for this type of functionality. Instead, we&#8217;re using  <strong>lightning:radioGroup</strong> with type &#8220;button&#8221;. This will setup our page links nicely in a row, with clickable links and active/inactive states already added. </p>



<p>Ready to get started? Let&#8217;s begin. </p>



<h3 class="wp-block-heading">Our Apex methods</h3>



<p>First and foremost, let&#8217;s start with the backend. If you guys are familiar with SOQL &#8211; which is Salesforce&#8217;s version of SQL, you know that we have the 3 necessary keywords for our paging to become possible: ORDER BY, LIMIT and OFFSET. </p>



<p><strong>ORDER BY</strong> &#8211; allows us to determine the order of our results. This makes it so that our result set will always follow a standard sort. This will make our paging deterministic and predictable.</p>



<p><strong>LIMIT</strong> &#8211; allows us to limit the results in the page. So when we click a page &#8211; we will only show these number of records.</p>



<p><strong>OFFSET</strong> &#8211; allows us to &#8220;skip&#8221; the records that we will not show. We&#8217;re &#8220;skipping&#8221; these records and start from the first record after our offset.  </p>



<p>I&#8217;m building a method that I can call from my lightning component. Note the &#8220;@auraEnabled&#8221; keyword. The function then takes 2 arguments: ofst and lmt. What it returns is simply our queried object, with the results using SOQL. </p>



<pre class="wp-block-code"><code lang="java" class="language-java line-numbers">@auraEnabled
public static List&lt;sObject&gt; getNewHires(Integer ofst, Integer lmt){
	List&lt;sObject&gt; onBoardingList = [SELECT
						Id,
						Name,
						FROM
						OnBoarding_Data__c
						ORDER BY Name DESC
						LIMIT :lmt
						OFFSET :ofst
						];
			return onBoardingList;
		}</code></pre>



<p>Now we need another method to find out the total number of records there are in the database. </p>



<pre class="wp-block-code"><code lang="java" class="language-java line-numbers">@auraEnabled
public static Integer getTotalItems(){
	Integer total = 0;
	String query = 'SELECT Id ';
	query += 'FROM OnBoarding_Data__c';
	List&lt;sObject&gt; onBoardingList = Database.query(query);
	total = onBoardingList.size();
return total;
}</code></pre>



<p>The above simply queries our same custom object, returning the total number of records.</p>



<p>My application uses a custom object for &#8220;on boarding&#8221; employees &#8211; so you will see OnBoarding references all through my sample code.  </p>



<p>Our simplified Apex is ready. Let&#8217;s move to the front end.  </p>



<h3 class="wp-block-heading">The HTML</h3>



<pre class="wp-block-code"><code lang="jsx" class="language-jsx line-numbers"> &lt;aura:attribute name="limitPerPage" type="Integer" default="16"/&gt;
 &lt;aura:attribute name="offset" type="Integer" default="0"/&gt;
 &lt;aura:attribute name="pagesArray" type="List" default="[]"/&gt;
 &lt;aura:attribute name="curpage" type="String" default="1"/&gt;</code></pre>



<p>In our HTML, we&#8217;re setting up 4 attributes that we need for our pagination. You should be able to tell from their names what they&#8217;re for. We&#8217;re also setting the default values in them. Note the &#8220;<strong>pagesArray</strong>&#8221; attribute &#8211; is an array that will house the page objects that we need for our paging system.</p>



<pre class="wp-block-code"><code lang="jsx" class="language-jsx line-numbers">&lt;aura:if isTrue="{! v.pagesArray.length &gt; 1 }"&gt;
      &lt;div class="pagingRow slds-grid slds-wrap slds-gutters"&gt;
      &lt;div aura:id="pagingWrap"
        class="slds-col slds-size_1-of-1 slds-large-size_12-of-12 pagingWrap"&gt;
        &lt;lightning:radioGroup
            type="button"
            aura:id="pager"
            name="pager"
            label=""
            options="{! v.pagesArray }"
            onchange="{!c.doPaging}"
            value="{!v.curpage}"
            /&gt;
      &lt;/div&gt;
      &lt;/div&gt;
    &lt;/aura:if&gt;</code></pre>



<p>The above is the output of our code. You see div wrappers that have Lighting Design System classes, along with aura directives to process our code. Such as our use of the <strong>aura:if</strong> &#8211; which checks the length of our pagesArray. Meaning &#8211; we&#8217;re only showing paging if there are pages to show.</p>



<p>You see our use of <strong>lightning:radioGroup</strong>. We also pass in &#8220;value&#8221; and &#8220;options&#8221; &#8211; which corresponds to our attributes we defined above.</p>



<p>We also have an onchange attribute calling our &#8220;<strong>doPaging</strong>&#8221; handler. We haven&#8217;t built this yet, but is coming up.</p>



<p>Let&#8217;s move on to our JavaScript.</p>



<h3 class="wp-block-heading">The JavaScript</h3>



<p>Let&#8217;s get down to business. We have our markup, we have our Apex waiting in the back end. All we need to do is tie them all up together. We do this with JavaScript &#8211; ideally in our helper file.</p>



<p>First, we create a &#8220;<strong>buildPaging</strong>&#8221; method. This method ideally fires on page load. But you can also call this method if you have some kind of filter mechanism. </p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript line-numbers">buildPaging : function(component,event, helper){
		helper.callServer(component,'c.getTotalItems', function(response){
			var ttl = response;
			var lmt = component.get('v.limitPerPage');
			var pages = Math.ceil(parseInt(ttl) / parseInt(lmt));
			var pagesArray = [];
			for(var i=1; i&lt;=pages; i++){
				var obj = {};
				obj['label'] = i.toString();
				obj['value'] = i.toString();
				pagesArray.push(obj);
			}
			component.set('v.pagesArray',pagesArray);
		},{});
	},</code></pre>



<p>First thing you&#8217;ll see is our helper.callServer() method. This is basically our means of calling our Apex code above. To find out more about callServer() &#8211; see the post &#8220;<a href="https://michaelsoriano.com/call-apex-from-lightning-components/">Call Apex from Lightning</a>&#8220;.</p>



<p>So from our total records, we can build our pagesArray. We call our <strong>getTotalItems</strong> from the backend, then we grab our &#8220;<strong>limitPerPage</strong>&#8221; attribute. We divide the total by the limit, and we&#8217;re doing a &#8220;<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/ceil">ceil()</a>&#8221; on it. This is so that we get a whole new page, even though there&#8217;s only 1 item in it.</p>



<p>Lastly, we&#8217;re building our pagesArray &#8211; but passing in the label and the value as an object. </p>



<p>Note the &#8220;<strong>toString()</strong>&#8221; method it. This is due to a bug with  <br><strong>lightning:radioGroup</strong>. It can only process strings. If you pass an integer &#8211; you would have to click it 2x to take effect! <em>Whatever</em>. </p>



<p>Let&#8217;s move on to our handler.  </p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript line-numbers">doPaging : function(component, event, helper){
		var lmt = component.get('v.limitPerPage');
		var val = event.getSource().get("v.value");
		var offset = parseInt((val-1) * lmt);
		component.set('v.curpage',val);
		component.set('v.offset',offset);
		helper.callServer(component,'c.getNewHires', function(response){
			if(response.length &gt; 0){
			component.set("v.newhires", response);
				}else{
					console.log('no records');
				}
		},{'ofst' : ofst, 'lmt' : lmt});
	},</code></pre>



<p> So first you see, lmt &#8211; which is static (set in our attribute). Then you see &#8220;val&#8221; &#8211; which is what was clicked. We get that number and multiply by the limit &#8211; so we get our <strong>offset</strong>. </p>



<p>We then call our Apex method with those parameters:</p>



<pre class="wp-block-code"><code lang="json" class="language-json line-numbers">{'ofst' : ofst, 'lmt' : lmt}</code></pre>



<p>Inside our callback, we simply set our response to the newly fetched data from our server. </p>



<h3 class="wp-block-heading">Conclusion</h3>



<p>And that&#8217;s about it. We&#8217;ve just built ourselves a very simplistic pagination using Lightning and Apex. There are many things we can do to enhance our code &#8211; like having a &#8220;previous&#8221; and &#8220;next&#8221; buttons &#8211; but I&#8217;ll leave that up to you. </p>



<p>Feel free to comment below.</p>
<p>The post <a href="https://michaelsoriano.com/how-to-create-simple-pagination-using-lightning-components-and-apex/">How to create simple Pagination using Lightning components and Apex</a> appeared first on <a href="https://michaelsoriano.com">Michael Soriano</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://michaelsoriano.com/how-to-create-simple-pagination-using-lightning-components-and-apex/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>Repeating Inputs in Salesforce Lightning Components</title>
		<link>https://michaelsoriano.com/repeating-inputs-in-salesforce-lightning-components/</link>
					<comments>https://michaelsoriano.com/repeating-inputs-in-salesforce-lightning-components/#comments</comments>
		
		<dc:creator><![CDATA[Michael Soriano]]></dc:creator>
		<pubDate>Fri, 23 Nov 2018 01:40:14 +0000</pubDate>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Salesforce]]></category>
		<category><![CDATA[Aura]]></category>
		<guid isPermaLink="false">http://michaelsoriano.com/?p=6788</guid>

					<description><![CDATA[<p>What we&#8217;re building: An input field that can be duplicated (repeated) as part of a form. This is particularly useful when you want to capture information that you want to separate in different lines, and you don&#8217;t really want to use a textarea. This way, we&#8217;re forcing our user&#8217;s to enter a value per input.  [&#8230;]</p>
<p>The post <a href="https://michaelsoriano.com/repeating-inputs-in-salesforce-lightning-components/">Repeating Inputs in Salesforce Lightning Components</a> appeared first on <a href="https://michaelsoriano.com">Michael Soriano</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>What we&#8217;re building: An input field that can be duplicated (repeated) as part of a form. This is particularly useful when you want to capture information that you want to separate in different lines, and you don&#8217;t really want to use a textarea. </p>



<p>This way, we&#8217;re forcing our user&#8217;s to enter a value per input.  In this scenario, we&#8217;re trying to grab a list a set of File Paths.<br></p>



<p>We&#8217;re using Lightning components, which is the framework Salesforce is using for their UI. A screenshot showing the pieces of what we want to accomplish is shown below.<br></p>



<p><img decoding="async" width="600" height="319" class="alignnone size-full wp-image-6794" src="https://michaelsoriano.com/wp-content/uploads/2018/10/repeating-fields.png" alt="Salesforce - lightning repeat field" srcset="https://michaelsoriano.com/wp-content/uploads/2018/10/repeating-fields.png 600w, https://michaelsoriano.com/wp-content/uploads/2018/10/repeating-fields-300x160.png 300w" sizes="(max-width: 600px) 100vw, 600px" /><br></p>



<p>See that we have inputs, a &#8220;More&#8221; link, and a &#8220;minus&#8221; sign &#8211; so we can remove the input directly.<br></p>



<p>Ready to build? Let&#8217;s begin.<br></p>



<p>Let&#8217;s start by defining an attribute in our .cmp file. Let&#8217;s call it &#8220;fileShares&#8221;, and its a &#8220;List&#8221; type. In Salesforce &#8211; a &#8220;List&#8221; is a an array in JavaScript. Here is how it looks</p>



<pre class="wp-block-code"><code lang="markup" class="language-markup">&lt;aura:attribute name="fileShares" type="List" default="[]"/></code></pre>



<p>Our array will hold a set of Objects, which reflects each of the input that we&#8217;re building.</p>



<p>Now we&#8217;re ready to create our markup. We&#8217;re using <strong>lightning:input </strong>&#8211; which is nothing but an &#8220;input&#8221; in HTML. We give it several attributes, which is defined below:</p>



<ul class="wp-block-list"><li>aura:id with a value of fileShare.id</li><li>value &#8211; with a value of fileShare.value</li><li>label &#8211; with a value of fileShare.label</li><li>class &#8211; with a value of &#8220;fileShares&#8221; (nothing to do with our object, but simply for styling)</li></ul>



<p>We also want to wrap it inside a DIV with a class of &#8220;<strong>fileSharesItem</strong>&#8220;.</p>



<p>Now let&#8217;s wrap it inside a <strong>aura:iteration </strong>tag, which is how you loop through items in Lightning.</p>



<pre class="wp-block-code"><code lang="markup" class="language-markup">&lt;aura:iteration items="{!v.fileShares}" var="fileShare" indexVar="ivar">
       &lt;div class="fileSharesItem">
            &lt;lightning:input
             aura:id="{!fileShare.id}"
             value="{!fileShare.value}"
             label="{!fileShare.label}"
             class="fileShares"/>
       &lt;/div>
&lt;/aura:iteration></code></pre>



<p>Notice that we&#8217;re looping through <strong>v.fileShares </strong>&#8211; which is the aura:attibute we first defined. We prefixed it with a &#8220;v.&#8221;, because in Lightning &#8211; this means &#8220;value provider&#8221;. We also have two important attributes in our iterator: var and indexVar. Our variable &#8220;fileShare&#8221; declared in &#8220;var&#8221;, while &#8220;indexVar&#8221; holds the index &#8211; we&#8217;re calling &#8220;iVar&#8221; (the counter).<br></p>



<p>Let&#8217;s move on to our controller. This is the JavaScript file, that we first initialize the value of <strong>v.fileShares</strong>. Add the code below (ideally inside an initialize method during load).</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">component.set('v.fileShares', {'label': 'Enter Path', 'value': '','id': 'fileShare1'});</code></pre>



<p>See that we&#8217;re using <strong>component.set() </strong>&#8211; and passing two parameters. The first is the property to set, then the value. In the case above, we&#8217;re setting up the &#8216;v.fileShares&#8217; with an object. This means that we want just one field to show when the page loads.</p>



<h3 class="wp-block-heading" id="adding-an-input">Adding an Input</h3>



<p>Let&#8217;s add the button that when clicked, a new input will be added to our form. Lighting supports data binding. This means that since we&#8217;ve binded our loop, all we worry about is the data. Remember our aura:iteration tag?</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">addMoreShareHandler : function(component, event, helper){
	var inputs = component.get("v.fileShares");
	var id = inputs.length+1;
	var obj = {
		'label': '',
		'value': '',
		'id': 'fileShare'+id}
		inputs.push(obj);
		component.set("v.fileShares", inputs);
},</code></pre>



<p>Try it out and you should see our input repeated. Pretty neat right? How about removing the input? Let&#8217;s tackle that below.</p>



<h3 class="wp-block-heading" id="the-remove-button">The Remove Button</h3>



<p>Let&#8217;s create an anchor tag &#8211; with a custom click handler. Also, let&#8217;s add a couple of attributes &#8211; so we know which one to remove. These attributes have to start with <strong>data- </strong>which is also known as &#8220;<a href="https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes">data-attributes</a>&#8220;. I&#8217;ll explain more in our handler.</p>



<pre class="wp-block-code"><code lang="markup" class="language-markup">&lt;a href="#" onclick="{!c.removeShareHandler}" data-idtoremove="{!fileShare.id}"
            data-index="{!ivar}" class=</code></pre>



<p>Now in our handler, we simply start with <strong>event.preventDefault()</strong> &#8211; which stops the link from behaving like a normal link. We don&#8217;t want the page to jump and refresh upon clicking.<br></p>



<p>Next, we grab the event, along with a property called <strong>currentTarget</strong>. What the currentTarget holds is information about what anchor tag was clicked.<br></p>



<p>So to access &#8220;<em>data-idtoremove</em>&#8220;, we do &#8220;<em>dataset.idtoremove</em>&#8220;</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">removeShareHandler : function(component, event, helper){
		event.preventDefault();
		var selectedItem = event.currentTarget;
                var idtoremove = selectedItem.dataset.idtoremove;
		var inputs = component.get("v.fileShares");
		for(var i=0;i&lt;inputs.length;i++){
			var obj = inputs[i];
			if(obj.id == idtoremove){
				inputs.splice(i,1)
			}
		}
		component.set("v.fileShares", inputs);
	}</code></pre>



<p>Then we loop through the inputs once again &#8211; by grabbing it from our component. We use .splice() to remove it from our array of objects.<br>Finally, let&#8217;s make the styles for our links.</p>



<h3 class="wp-block-heading" id="the-css">The CSS:</h3>



<p>For the remove link, we&#8217;re really trying to make it look like a &#8220;minus&#8221; button. We&#8217;re doing that with <strong>border-radius: 50%, </strong>along with a background color and a faint box-shadow. The rest of the CSS is mainly for positioning and sizing.</p>



<pre class="wp-block-code"><code lang="css" class="language-css">.THIS .slds-form-element.fileShares {
  margin-bottom:-5px;
}
.THIS .fileSharesItem {
  position:relative;
}
.THIS .removeShare {
  position: absolute;
  z-index: 999;
  right: -8px;
  top: 15px;
  border: 1px solid #ccc;
  width: 21px;
  line-height: 17px;
  padding: 0 0 2px 0;
  text-align: center;
  border-radius: 50%;
  font-size: 22px;
  background: #fff;
  box-shadow: 2px 2px 0 #e9e9e9;
}
.THIS .removeShare:hover,
.THIS .removeShare:active,
.THIS .removeShare:focus {
  text-decoration:none;
  background:#ebebeb;
}</code></pre>



<p>Finally, we&#8217;re setting some hover styles by using <strong>:hover</strong>, <strong>:active</strong> and <strong>:focus </strong>also known as &#8220;pseudo selectors&#8221;. We simply want the cursor to change into a pointer, along with a subtle background change.<br>The final output:</p>



<p><br><img decoding="async" width="410" height="257" class="alignnone size-full wp-image-6792" src="https://michaelsoriano.com/wp-content/uploads/2018/10/repeating-fields.gif" alt="Salesforce repeating fields"><br></p>



<p>So there it is. We just made a quick set of repeating inputs in Lightning. This also is a good crash course into Salesforce&#8217;s shiny new framework &#8211; which is gaining more popularity in the world of enterprise application development.<br></p>



<p>If you find this tutorial useful, or would like to see more &#8211; leave your comments below.</p>
<p>The post <a href="https://michaelsoriano.com/repeating-inputs-in-salesforce-lightning-components/">Repeating Inputs in Salesforce Lightning Components</a> appeared first on <a href="https://michaelsoriano.com">Michael Soriano</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://michaelsoriano.com/repeating-inputs-in-salesforce-lightning-components/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>Let&#8217;s build a Map Application using Leaflet and Lightning Components</title>
		<link>https://michaelsoriano.com/lets-build-map-application-using-leaflet-and-lightning-components/</link>
					<comments>https://michaelsoriano.com/lets-build-map-application-using-leaflet-and-lightning-components/#comments</comments>
		
		<dc:creator><![CDATA[Michael Soriano]]></dc:creator>
		<pubDate>Sat, 15 Sep 2018 23:57:59 +0000</pubDate>
				<category><![CDATA[Salesforce]]></category>
		<category><![CDATA[Apex]]></category>
		<category><![CDATA[Aura]]></category>
		<category><![CDATA[lightning]]></category>
		<guid isPermaLink="false">http://michaelsoriano.com/?p=6575</guid>

					<description><![CDATA[<p>Salesforce&#8217;s Lightning component system is quite a robust framework where you can build full pledged single-page applications in a heartbeat. I especially like it&#8217;s built-in SLDS (styles), so all you have to really think about is the logic of your application. In this walk trough, we&#8217;re building a real life map application with Lightning. We&#8217;re [&#8230;]</p>
<p>The post <a href="https://michaelsoriano.com/lets-build-map-application-using-leaflet-and-lightning-components/">Let&#8217;s build a Map Application using Leaflet and Lightning Components</a> appeared first on <a href="https://michaelsoriano.com">Michael Soriano</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Salesforce&#8217;s Lightning component system is quite a robust framework where you can build full pledged single-page applications in a heartbeat. I especially like it&#8217;s built-in SLDS (styles), so all you have to really think about is the logic of your application. In this walk trough, we&#8217;re building a real life map application with Lightning. </p>



<p>We&#8217;re using Google Places for our city lookup, as well as Leaflet for our map and finally Chatter for our chat component.<br></p>



<p>The goal is to have pins on the map &#8211; which is on the right side of our page. These pins are also shown in a list format on the left hand side of the page. Once a pin is clicked, the list on the left hand side is replaced by the pin details, along with the ability to chat about that specific pin directly below. When the &#8220;Close&#8221; button is clicked, the list re-appears, as well as the map zooms to its original view.</p>



<p><br>The same behavior is achieved when the pin on the map is clicked.</p>



<p><br><img decoding="async" width="930" height="465" class="alignnone size-full wp-image-6663" style="border: 1px solid #ededed;" src="https://michaelsoriano.com/wp-content/uploads/2018/07/map-application3.gif" alt="Salesforce Map"><br></p>



<p>We also have a custom form, that allows us to add a pin right in the same page. The form has an auto suggest field for the cities.<br></p>



<p>Note that this is going to be a high level tutorial. You should be well versed in Lightning Components and JavaScript to follow along. A working knowledge of Salesforce is also needed.<br></p>



<p>Read to get started? Let&#8217;s begin.</p>



<h3 class="wp-block-heading" id="setting-things-up">Setting things Up</h3>



<p>Before we can actually start coding, let&#8217;s back up and think about what we need. We will need a map software.&nbsp; We need to store the locations in a custom object in Salesforce. And we need an Apex class to fetch these records for us. Seems simple enough? Let&#8217;s continue.</p>



<p><br><strong>Static Resources</strong><br></p>



<p>We&#8217;re using Leaflet &#8211; an open source map software which allows us to build a map on the page. All we need to do is pass it an array of locations (Longitude + Latitude) and Leaflet will populate magically. We also need LeafletMarkerCluster, an add-on to Leaflet, which allows us to bundle our pins together. This prevents the ugly grouping of many pins together.<br></p>



<p>So add these two zip files as static resources to Salesforce:</p>



<ul class="wp-block-list"><li><a href="https://michaelsoriano.com/wp-content/uploads/2019/05/leaflet.zip">Leaflet</a></li><li><a href="https://michaelsoriano.com/wp-content/uploads/2019/05/leafletMarkerCluster.zip">LeafletMarkerCluster</a></li></ul>



<p><img decoding="async" width="579" height="500" class="alignnone size-full wp-image-6655" src="https://michaelsoriano.com/wp-content/uploads/2018/07/static-resources.png" alt="Static Resources" srcset="https://michaelsoriano.com/wp-content/uploads/2018/07/static-resources.png 579w, https://michaelsoriano.com/wp-content/uploads/2018/07/static-resources-300x259.png 300w" sizes="(max-width: 579px) 100vw, 579px" /><br></p>



<p><strong>Custom Object</strong><br></p>



<p>Each pin on the map is a record from a Custom Object in Salesforce. Let&#8217;s call ours &#8220;Pin&#8221;. Go ahead and build that custom object with the fields shown below.</p>



<p><br><img decoding="async" width="803" height="644" class="alignnone size-full wp-image-6671" src="https://michaelsoriano.com/wp-content/uploads/2018/07/custom-obj-pin.png" alt="custom object" srcset="https://michaelsoriano.com/wp-content/uploads/2018/07/custom-obj-pin.png 803w, https://michaelsoriano.com/wp-content/uploads/2018/07/custom-obj-pin-300x241.png 300w, https://michaelsoriano.com/wp-content/uploads/2018/07/custom-obj-pin-768x616.png 768w" sizes="(max-width: 803px) 100vw, 803px" /><br>You also might need to enter a few records. Since we&#8217;re dealing with coordinates, you will need to Google maps and grab this information. Don&#8217;t worry &#8211; this is just for the prototype. We are building our own custom form &#8211; that will take care of all this information for us.<br></p>



<p><strong>The Apex Class</strong><br></p>



<p>An Apex Class can behave sort of like a hash table that can hold our functions. This is how we&#8217;re going to interact with data from our Lightning components. Go ahead and create a class called &#8220;Pin&#8221;. Let&#8217;s add a method in there that grabs all of our Pins as well:</p>



<pre class="wp-block-code"><code lang="java" class="language-java">public with sharing class Pin {
    public static List&lt;Pin__c&gt; getPins(){
        String sql = 'select Name, City__c, Lat__c, Long__c, Content__c, 
        Country__c, Region__c, Continent__c from Pin__c ORDER BY CreatedDate  
        DESC';
        List&lt;Pin__c&gt; PinList = Database.query(sql);
        return PinList;
    }
}</code></pre>



<p>Above is a class that has one static method &#8220;<strong>getPins</strong>&#8220;. This means that we don&#8217;t have to instantiate the class to use the method. The <strong>@auraEnabled&nbsp;</strong>declaration also make it callable directly from our Lightning components.</p>



<p><br><strong>Component</strong><br></p>



<p>Once that&#8217;s done, go ahead and create a Lightning component &#8211; let&#8217;s call ours &#8220;<strong>Pin</strong>&#8220;. Open <strong>pin.cmp</strong> and add the code below:</p>



<pre class="wp-block-code"><code lang="markup" class="language-markup">
&lt;aura:component implements="flexipage:availableForAllPageTypes"  access="global" controller="Pin"&gt;
    &lt;ltng:require styles="{!$Resource.leaflet + '/leaflet.css'}" /&gt;
    &lt;ltng:require styles="{!$Resource.leafletMarkerCluster + '/leafletMarerClusterDefault.css'}" /&gt;
    &lt;ltng:require styles="{!$Resource.leafletMarkerCluster + '/leafletMarerCluster.css'}" /&gt;
    &lt;ltng:require scripts="{!join(',',$Resource.leaflet + '/leaflet.js', $Resource.leafletMarkerCluster + '/leafletMarerCluster.js')}" afterScriptsLoaded="{!c.jsLoaded}" /&gt;
&lt;/aura:component&gt;</code></pre>



<p>You will see that all we&#8217;re doing is setting our static resources up in our component file. We&#8217;re also doing&nbsp;<strong>controller=&#8221;Pin&#8221; </strong>in our component declaration. This means that we&#8217;re going to create an Apex class called &#8220;Pin&#8221;. We&#8217;ll get to that later.</p>



<p>Also note we have <strong>afterScriptsLoaded=&#8221;{!c.jsLoaded}&#8221; </strong>in our lightning scripts tag.&nbsp; This is because we want the function <strong>jsLoaded</strong> to run as soon as our scripts are loaded. We don&#8217;t have this function yet &#8211; so loading the page will cause an error. We&#8217;ll get to this function soon.</p>



<p>Let&#8217;s continue building the markup.</p>



<p>Still in our .cmp file, after our scripts and styles &#8211; add our markup below :</p>



<pre class="wp-block-code"><code lang="markup" class="language-markup">&lt;aura:attribute name="pins" type="List" default="[]"/&gt;
&lt;aura:attribute name="singlePin" type="Object" default="{}"/&gt;
&lt;div class="slds-grid"&gt;
        &lt;div class="leftcol-wrap slds-col slds-size_1-of-3"&gt;
            &lt;!--THIS IS THE LEFT HAND COLUMN, WHERE THE LOCATIONS WILL GO--&gt;
            &lt;!--THIS IS ALSO WHERE THE SINGLE LOCATION DETAIL WILL GO--&gt;
        &lt;/div&gt;&lt;!--leftcol-wrap--&gt;
        &lt;div class="map-wrap slds-col slds-size_2-of-3"&gt;
            &lt;div class="map" id="map" aura:id="map"&gt;&lt;/div&gt;
        &lt;/div&gt;&lt;!--end map-wrap--&gt;
&lt;/div&gt; &lt;!--end slds-grid--&gt;</code></pre>



<p>The &#8220;<strong>aura:attribute</strong>&#8221; named &#8220;<strong>pins</strong>&#8221; is simply a holder for the pins we&#8217;re grabbing from the controller. </p>



<p>More on this later.</p>



<p>The&nbsp;&#8220;<strong>aura:attribute</strong>&#8221; named &#8220;<strong>singlePin</strong>&#8221; is also a holder &#8211; for a pin that&#8217;s in focus. Again, more on this later.</p>



<p>This sets up our page. We&#8217;re splitting the page in two, one column is smaller (size_1-of-3) and the other bigger (size_2-of-3). We&#8217;re using built in Salesforce classes, with the prefix &#8220;slds&#8221;, stands for <a href="https://www.lightningdesignsystem.com">Salesforce Lightning Design System</a>. In case you&#8217;re not familiar with it &#8211; it&#8217;s sort of like Bootstrap and React fused into a single framework.</p>



<h3 class="wp-block-heading" id="the-map">The Map</h3>



<p>So we&#8217;re ready to load the page and initialize our Leaflet map. We have our temp data in our custom object, we should have our component &#8211; along with the JavaScript files in place. Let&#8217;s write the&nbsp;<strong>jsLoaded</strong>() function (this is called when our scripts are done loading):</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">jsLoaded: function(component, event, helper) {
	var mapOptions = {
		zoomControl: true,
		zoomAnimation:false, //fixes the error when zooming in...
		markerZoomAnimation:true
	}
        var map = L.map('map', mapOptions)
        map.setView([48.85661400000001, 2.3522219], 2);
        map.scrollWheelZoom.disable();
        helper.map = map;
        L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}', {attribution: 'Location'}).addTo(map);
        helper.callServer(component,'c.getPins', function(response){
        	component.set('v.pins',response);
        	helper.buildMap(component, event, helper, response);
        },{});
	}</code></pre>



<p>Okay, a lot going on here. We&#8217;re setting some map default options (for more info on Leaflet, see their <a href="https://leafletjs.com/reference-1.3.2.html">documentation</a>).&nbsp;&nbsp;We also have a very important helper function called &#8220;.<strong>callServer()</strong>&#8220;. This function is responsible for making the call to our Apex class, and returns our data. Note that I talk about <strong>callServer</strong> in a previous <a href="https://michaelsoriano.com/call-apex-from-lightning-components/">post</a>. Simply add this function in your <strong>PinHelper.js</strong> file and that should be good to go.<br>Inside our callback we&#8217;re setting the <strong>v.pins</strong>&nbsp;in our .cmp file &#8211; which is an array of objects that came back from our server.</p>



<p>Right after we have a function called .<strong>buildMap()</strong>&nbsp;&#8211; which is a pretty big function and discussed in detail below.</p>



<h3 class="wp-block-heading" id="the-map">The Map</h3>



<p>So our pins our fetched from the server. I don&#8217;t know if you remember, that we are using a Leaflet add-on called <strong>LeafletMarkerCluster</strong> &#8211; which is what does the clustering of the pins &#8211; that are in the same proximity. What this does is &#8211; it creates a nice visual &#8211; the number of pins in a specific grouping, that you can click &#8211; and it will zoom in further to show the pins.</p>



<p>It also has a nice &#8220;spider&#8221; effect &#8211; for the clusters &#8211; which is really cool:</p>



<p><img decoding="async" width="669" height="380" class="alignnone size-full wp-image-6666" style="border: 1px solid #ededed;" src="https://michaelsoriano.com/wp-content/uploads/2018/07/clusters.gif" alt="Cluster"><br>So what we need is a way to group our pins. Notice our custom object earlier &#8211; we have a field called &#8220;Region&#8221;. A region is similar to a &#8220;State&#8221; in the United States. So every pin that share the same region &#8211; will be clustered. Make sure your test data have pins that have the same region, and some that don&#8217;t.</p>



<p>Don&#8217;t worry &#8211; we don&#8217;t have to figure out what region our pins need to be &#8211; remember we&#8217;re building our own form.</p>



<p><strong>The .buildMap() function</strong></p>



<p>Now let&#8217;s dig in to the actual code that adds and groups the pins to the map. Open <strong>PinHelper.js</strong> and add the code below:</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">map : {},
mapLayers : {},
markerGroups : [],
markerList : [],
buildMap : function(component, event, helper, response){
        var map = helper.map;
        function onMarkerClick(e){
            //TODO: ADD LOGIC WHEN MARKER IS CLICKED
        }
        function onlyUnique(value, index, self) {
            return self.indexOf(value) === index;
        }
        function popupHtml(pinName){
            return '&lt;strong&gt;' + pinName + '&lt;/strong&gt;';
        }
        var markerGroups = helper.markerGroups;
        for(var y=0; y&lt;markerGroups.length;y++){
            markerGroups[y].clearLayers();
        }
        var groups = [];
        for(var i=0; i&lt;response.length;i++){
           groups.push(response[i].Region__c);
        }
        var uniqueGroups = groups.filter(onlyUnique);
        var markerOpts = {
            draggable : false
        }
        var markerList = [];
        for(var x=0; x&lt;uniqueGroups.length;x++){
            var markers;
            markers = L.markerClusterGroup();
            helper.markerGroups.push(markers);
            for(var i=0; i&lt;response.length;i++){
                if(response[i].Region__c == uniqueGroups[x]){
                    markerOpts.alt = response[i].Id; //marker options
                    markerOpts.icon = L.icon({iconUrl : 'YOURICONIMAGE.png'});
                    var mark = L.marker([response[i].Lat__c,response[i].Long__c],markerOpts).on('click', onMarkerClick);
                    var popup = mark.bindPopup(popupHtml(response[i].Name));
                    popup.on('popupclose',function(){
                        helper.closeSinglePin(component, event, helper);
                    })
                    markers.addLayer(mark).addTo(map);
                    markerList[response[i].Id]=mark;
                }
            }
        }
        helper.markerList = markerList;
    },</code></pre>



<p>First, let&#8217;s set some variables in our helper (lines 1-4). These will act as a container as we pass them around from our controller to helper and vice versa.</p>



<p>Then the actual buildMap() function. We have gone through our pins and determined the unique regions and stuffed them into&nbsp;<strong>helper.markerGroups. </strong>Now starting in line 39, we loop through each of pin and add them to the map &#8211; according to their respective groups (region). Passing along the necessary options for each pin.</p>



<p>Your map should now load with the clusters and the pins.</p>



<h3 class="wp-block-heading" id="the-list-of-pins-left-side">The List of Pins (Left Side)</h3>



<p>On the left side of the application &#8211; we show all of the pins &#8211; sorted by latest entry. Remember that we set our pins as a component attribute in our <strong>jsLoaded() </strong>function? Now all we need to do is loop through this in our component. But first, we have to check if there&#8217;s a&nbsp;<strong>singlePin </strong>&#8211; why you ask? This is to determine if we clicked on a marker on the map OR we clicked on any of the item in our list (which we&#8217;re still building).</p>



<p>We do this by using the&nbsp;<strong>aura:if </strong>directive<strong>.</strong></p>



<p>The code below goes into the left hand section.</p>



<pre class="wp-block-code"><code lang="markup" class="language-markup">&lt;aura:if isTrue="{!v.singlePin.Id}"&gt;
	&lt;div class="singlePin" aura:id="singlePin"&gt;
		&lt;lightning:button class="closeSinglePin" onclick="{!c.closeSinglePin}"&gt;Close&lt;/lightning:button&gt;
		 &lt;h3&gt;{!v.singlePin.Name}&lt;/h3&gt;
		 &lt;div class="singleMeta"&gt;
			&lt;span&gt;{!v.singlePin.Region__c}, &amp;nbsp;&lt;/span&gt;
			&lt;span&gt;{!v.singlePin.Continent__c}&lt;/span&gt;
		 &lt;/div&gt;
		 &lt;div class="singleContent"&gt;
			 &lt;aura:unescapedHtml value="{!v.singlePin.Content__c}" /&gt;
		 &lt;/div&gt;
		 &lt;forceChatter:publisher context="RECORD" recordId="{!v.singlePin.Id}" /&gt;
		 &lt;forceChatter:feed type="Record" subjectId="{!v.singlePin.Id}" /&gt;
	&lt;/div&gt;
	&lt;aura:set attribute="else"&gt;
		&lt;h3 class="pinstitle"&gt;Locations&lt;/h3&gt;
		&lt;aura:iteration items="{!v.pins}" var="pin"&gt;
		&lt;lightning:button class="pinListItem" name="{!pin.Id}" onclick="{!c.markerClick}" &gt;
			&lt;div class="pin-name"&gt;{!pin.Name}&lt;/div&gt;
			&lt;div class="pin-meta"&gt;
				&lt;span class="pin-region"&gt;{!pin.Region__c}&lt;/span&gt;&amp;nbsp;
				&lt;span class="pin-country"&gt;{!pin.Country__c}&lt;/span&gt;
			&lt;/div&gt;
		&lt;/lightning:button&gt;
		&lt;/aura:iteration&gt;
	&lt;/aura:set&gt;
&lt;/aura:if&gt;</code></pre>



<p>Let&#8217;s look at the singlePin scenario first &#8211; which is when an item is clicked. We are simply displaying some data from the singlePin &#8211; along with a button to close it (this <strong>.closeSinglePin() </strong>is not built yet). Then notice the use of&nbsp;&nbsp;<strong>forceChatter:publisher</strong> and&nbsp;<strong>forceChatter:feed</strong>. These components are built in to Lightning &#8211; all we need to do is pass it a Id &#8211; and voila!</p>



<p>This will display our single pin nicely &#8211; along with a Chatter component right below it.</p>



<p><br><img decoding="async" width="534" height="551" class="alignnone size-full wp-image-6664" style="border: 1px solid #ededed;" src="https://michaelsoriano.com/wp-content/uploads/2018/07/chatter.gif" alt="Locations with Chatter"><br></p>



<p>For the list, you see how we wrapped each pin as a <strong>lightning:button</strong>? That&#8217;s because we can click each item and something will happen. We have a <strong>c.markerClick </strong>handler on each item that we haven&#8217;t built yet.<br>The rest is simply markup of the pin details. Let&#8217;s create that handler.</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">markerClick : function(component, event, helper){
	var markerId = event.getSource().get("v.name");
	var marker = helper.markerList[markerId];
	var markerGroupId = marker['__parent']['_group']['_leaflet_id'];
	var parentChildCount = marker['__parent']['_childCount'];
	if(parentChildCount &gt; 1){
		 for(var i=0; i&lt;helper.markerGroups.length; i++){
			if(helper.markerGroups[i]._leaflet_id == markerGroupId){
				helper.markerGroups[i].zoomToShowLayer(marker, function () {
					console.log('zoomed to layer');
					marker.fire('click')
					marker.openPopup();
				});
			}
		 }
	}else{
		marker.fire('click')
		marker.openPopup();
	}
}</code></pre>



<p>Remember, each item in our list &#8211; when clicked, will have the same behavior as clicking the pin (marker) on the map. So the above code is simply a trigger (using <strong>marker.fire()</strong>). But the check before that is to determine &#8211; if the marker is inside a cluster. If it is &#8211; we zoom to the layer first (using&nbsp;<strong>.zoomToShowLayer()</strong>), then fire.</p>



<p>Also, remember that we don&#8217;t have any behavior yet in when we click our pins (we have it as a TODO in our <strong>.buildMap()</strong> function above). Let&#8217;s go back and create that now.</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">function onMarkerClick(e){
	component.set('v.singlePin',{});  //resets to {}
	var id = e.target.options.alt;
	var latLong = e.target.getLatLng();
	if(e.target['_preSpiderfyLatlng']){
		latLong = e.target['_preSpiderfyLatlng']
	}
	map.setView(latLong);
	var pins = component.get('v.pins');
	for(var x=0; x&lt;pins.length;x++){
		if(pins[x].Id == id){
			component.set('v.singlePin',pins[x]);
		}
	}
}</code></pre>



<p>The handler above reset&#8217;s the singlePin to an empty object. Then we get the lat and long from the marker (we get it from &#8220;<strong>e</strong>&#8221; &#8211; or the <strong>event</strong>). We set the view on the map according to the coordinates.&nbsp; Then finally &#8211; we loop through our pins &#8211; and set the <strong>v.singlePin&nbsp;</strong>into the one clicked.</p>



<p>Lastly, the&nbsp;<strong>.closeSinglePin() </strong>function:</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">closeSinglePin : function(component, event, helper){
        var map = helper.map;
        var defaultChatterFeed = component.find('defaultChatterFeed');
        var singlePin = component.find('singlePin');
        $A.util.removeClass(defaultChatterFeed, 'slds-hide');
        $A.util.addClass(singlePin, 'slds-hide');
        component.set('v.singlePin',{});
	map.setView([48.85661400000001, 2.3522219], 2);
        map.closePopup();
    },</code></pre>



<p>The above simply hides our Single Pin and Chatter, resets the singlePin variable, then resets the map.</p>



<h3 class="wp-block-heading" id="the-form">The Form</h3>



<p>Finally, we come to the data entry section &#8211; where it will make it easy for us to add pins to our map. This form will have the necessary fields for our custom object &#8211; but most importantly, the auto-suggest field &#8211; that will auto populate the longitude, latitude, region etc.</p>



<p><img decoding="async" width="747" height="326" class="alignnone size-full wp-image-6665" style="border: 1px solid #ededed;" src="https://michaelsoriano.com/wp-content/uploads/2018/07/cities.gif" alt="City autocomplete"></p>



<p><br>I wrote a <a href="https://michaelsoriano.com/lightning-component-google-places/">tutorial</a> about this Auto-suggest field &#8211; using Google Places API, so I&#8217;m not going to get into that code. I&#8217;m simply going to go through the rest of the logic &#8211; that makes our form.</p>



<p>First off, we&#8217;re showing our form in a modal. Still in the same component, let&#8217;s add this to the lower section of our <strong>.cmp</strong> file:</p>



<pre class="wp-block-code"><code lang="markup" class="language-markup">&lt;lightning:button name="openNewPin" onclick="{!c.openNewPin}"&gt;Add New&lt;/lightning:button&gt;
&lt;aura:attribute name="newPin" type="Pin__c" default="{}"/&gt;
&lt;aura:attribute name="predictions" type="List" default="[]"/&gt;
&lt;aura:attribute name="validationErrors" type="List" default="[]"/&gt;
&lt;div role="dialog" tabindex="-1" aura:id="newPinModal" class="slds-modal"&gt;
	&lt;div class="slds-modal__container"&gt;
		&lt;div class="slds-modal__header"&gt;
			&lt;button class="slds-button slds-modal__close slds-button--icon-inverse" title="Close" onclick="{!c.closenewPin}"&gt;&lt;span class="slds-assistive-text"&gt;Close&lt;/span&gt;
			&lt;/button&gt;
			&lt;h2 id="header43" class="slds-text-heading--medium"&gt;Add New Pin&lt;/h2&gt;
		&lt;/div&gt;
		&lt;div class="slds-modal__content slds-p-around--medium"&gt;
			&lt;div&gt;
				&lt;aura:if isTrue="{!v.validationErrors.length &gt; 0}"&gt;
				&lt;ul class="validationErrorList"&gt;
				&lt;aura:iteration items="{!v.validationErrors}" var="validationError"&gt;
					&lt;li&gt;{!validationError}&lt;/li&gt;
				&lt;/aura:iteration&gt;
				&lt;/ul&gt;
				&lt;/aura:if&gt;
				&lt;lightning:input label="Name" value="{!v.newPin.Name}"/&gt;
				&lt;label style="margin:12px 0 3px; display:block;"&gt;Content&lt;/label&gt;
				&lt;lightning:inputRichText value="{!v.newPin.Content__c}" /&gt;
				&lt;div style="position:relative;"&gt;
				&lt;lightning:input label="City"
					value="{!v.newPin.City__c}"
					onchange="{!c.getCities}" /&gt;
					&lt;aura:if isTrue="{!v.predictions.length &gt; 0}"&gt;
						&lt;ul class="city_predictions"&gt;
							&lt;aura:iteration items="{!v.predictions}" var="prediction"&gt;
							&lt;li class="slds-listbox__item"&gt;
								&lt;a onclick="{!c.getCityDetails}" data-placeid="{!prediction.place_id}"&gt;{!prediction.description}&lt;/a&gt;
							&lt;/li&gt;
							&lt;/aura:iteration&gt;
						&lt;/ul&gt;
					&lt;/aura:if&gt;
				&lt;lightning:input value="{!v.newPin.Lat__c}" class="slds-hide" /&gt;
				&lt;lightning:input value="{!v.newPin.Long__c}" class="slds-hide"/&gt;
				&lt;lightning:input value="{!v.newPin.Region__c}" class="slds-hide"/&gt;
				&lt;lightning:input value="{!v.newPin.Country__c}"  class="slds-hide"/&gt;
				&lt;/div&gt;
			&lt;/div&gt;
		&lt;/div&gt;
		&lt;div class="slds-modal__footer"&gt;
			&lt;lightning:button onclick="{!c.saveRecord}"&gt;Submit&lt;/lightning:button&gt;
		&lt;/div&gt;
	&lt;/div&gt;
&lt;/div&gt;
&lt;!--end new pin--&gt;
&lt;div class="slds-backdrop " aura:id="Modalbackdrop"&gt;&lt;/div&gt;
&lt;lightning:notificationsLibrary aura:id="notifLib"/&gt;&lt;!--toast message--&gt;</code></pre>



<p>The&nbsp;<strong>lightning:button </strong>in the beginning, is what opens up the modal. It&#8217;s up to you how you want to show this button, and who to show it to.</p>



<p>The next three lines you&#8217;ll notice that we&#8217;re setting some new attributes. Again, these act as a containers for the variables we&#8217;re using in our component.</p>



<p>The SLDS dialog box contain a close button, a header, a footer&nbsp; and a backdrop. The close button triggers a function&nbsp;<strong>closenewPin()&nbsp;</strong>when clicked. We&#8217;ll get to this later. Then we have a validation error list, then the form fields.</p>



<p>The &#8220;City&#8221; has an onchange handler called&nbsp;<strong>getCities() </strong>&#8211; which grabs the predictions from our Apex class. Again this was in a <a href="https://michaelsoriano.com/lightning-component-google-places/">previous tutorial</a> and find out how it&#8217;s done there.&nbsp; The&nbsp;<strong>lightning:input </strong>fields that have a class &#8220;<strong>slds-hide</strong>&#8221; &#8211; are hidden fields. These fields are automatically filled &#8211; and will require no user interaction.</p>



<p>Finally, the&nbsp;<strong>lightning:button&nbsp;</strong>that takes care of saving the record.</p>



<p>Oh, we also have&nbsp;<strong>lightning:notificationsLibrary </strong>at the very end &#8211; which is Salesforce&#8217;s toast notification. We use this for messaging when successful.</p>



<p><strong>Saving the Record</strong></p>



<p>First let&#8217;s take care of the entering our record. Open the controller and add the method &#8220;<strong>saveRecord</strong>&#8221; below:</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">saveRecord : function(component, event, helper){
	var newPin = component.get('v.newPin');
	var str = JSON.stringify(newPin);
	//validation
	var errors = [];
	if(!newPin['Name']){
		errors.push('Name cannot be empty');
	}
	if(!newPin['City__c']){
		errors.push('City cannot be empty');
	}
	component.set('v.validationErrors', errors);
	if(errors.length &gt; 0){
		return false;
	}
	helper.callServer(component,"c.savePin",function(data){
		helper.callServer(component,'c.getPins', function(response){
			component.set('v.Pins',response);
			component.set('v.newPin',{});
			helper.buildMap(component, event, helper, response);
			helper.closeModal(component, 'newPinModal');
			helper.showToast(component, 'success', 'A Pin has been added.');
		},{});
	},{"strsRecord" : str});
},</code></pre>



<p>This function gets called as soon as the user clicks the &#8220;<strong>Save</strong>&#8221; button. First, we do some validation &#8211; and see if our required fields are filled in. If not, we set the <strong>validationErrors&nbsp;</strong>array up and exits.</p>



<p>Otherwise, we do a <strong>.callServer() </strong>twice. First to save the pin &#8211; and inside it&#8217;s callback, we do another&nbsp;<strong>.callServer() </strong>to get all of the pins. This is so that once we add a new pin &#8211; it grabs the new set of pins &#8211; so we can see it right away on the map. Remember I discussed about the <strong>.callServer() </strong>function in &#8220;<a href="https://michaelsoriano.com/call-apex-from-lightning-components/">Call Apex from Lightning components</a>&#8220;.</p>



<p>This is the part that actually does the saving to the database. Add this to your Apex class &#8211; as another method:</p>



<pre class="wp-block-code"><code lang="java" class="language-java">@AuraEnabled
public static Pin__c savePin(String strsRecord){
	Pin__c strsRecord2 = (Pin__c)JSON.deserialize(strsRecord,Pin__c.class);
	try{
		if(strsRecord2 != null){
			insert strsRecord2;
		}
	}catch (Exception ex){
	}
	return strsRecord2;
}</code></pre>



<p>Finally, we call&nbsp;<strong>.buildMap(), .closeModal() </strong>and <strong>.showToast(). </strong>You get what those functions are doing. Let&#8217;s add what&#8217;s missing in our helper. Open <strong>PinHelper.js</strong>&nbsp;and add the code below:</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">closeModal : function(component, modal){
	var cmpTarget = component.find(modal);
	var cmpBack = component.find('Modalbackdrop');
	$A.util.removeClass(cmpBack,'slds-backdrop--open');
	$A.util.removeClass(cmpTarget, 'slds-fade-in-open');
},
openModal : function(component,modal){
	var cmpTarget = component.find(modal);
	var cmpBack = component.find('Modalbackdrop');
	$A.util.addClass(cmpTarget, 'slds-fade-in-open');
	$A.util.addClass(cmpBack, 'slds-backdrop--open');
},
showToast : function(component, variant, msg){
	var toastSettings = {
		"title": variant,
		"message": msg,
		"variant" : variant,
		"mode" : "dismissable"
	}
	component.find('notifLib').showToast(toastSettings);
},</code></pre>



<p>The helper functions above are pretty self-explanatory. For further explanation &#8211; especially about the utilities available in the $A object &#8211; refer to this <a href="https://salesforce.stackexchange.com/questions/54032/what-are-the-available-a-javascript-functions-in-lightning">question</a> in StackOverflow.</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">closeNewPin : function(component, event, helper){
		helper.closeModal(component, 'newPinModal');
},
openNewPin : function(component, event, helper){
	helper.openModal(component, 'newPinModal');
},
closeSinglePin : function(component, event, helper){
	helper.closeSinglePin(component, event, helper)
},</code></pre>



<p>Lastly, the above methods are in our helper, but we need to access them using our controller. Simply add the code below to our controller:</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">closeNewPin : function(component, event, helper){
		helper.closeModal(component, 'newPinModal');
},
openNewPin : function(component, event, helper){
	helper.openModal(component, 'newPinModal');
},
closeSinglePin : function(component, event, helper){
	helper.closeSinglePin(component, event, helper)
},</code></pre>



<p>And after all is in place, our form should now be working:</p>



<p><img decoding="async" width="633" height="547" class="alignnone size-full wp-image-6700" src="https://michaelsoriano.com/wp-content/uploads/2018/07/form.gif" alt="Form"></p>



<h3 class="wp-block-heading" id="conclusion">Conclusion</h3>



<p>There you have it. A cool map with events, clusters, a custom form &#8211; a good start of a real world application you can build inside Salesforce. Keep in mind these are mostly using Lightning &#8211; unless we had to build it ourselves. </p>



<p>Next up should be filtering the results, adding a better Hover callout on the pins, maybe even having the latest chatter in the hover. The possibilities are endless.</p>
<p>The post <a href="https://michaelsoriano.com/lets-build-map-application-using-leaflet-and-lightning-components/">Let&#8217;s build a Map Application using Leaflet and Lightning Components</a> appeared first on <a href="https://michaelsoriano.com">Michael Soriano</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://michaelsoriano.com/lets-build-map-application-using-leaflet-and-lightning-components/feed/</wfw:commentRss>
			<slash:comments>25</slash:comments>
		
		
			</item>
		<item>
		<title>Build a Basic Page with Salesforce Data using Heroku Connect and NodeJS</title>
		<link>https://michaelsoriano.com/build-a-basic-page-with-salesforce-data-using-heroku-connect-and-nodejs/</link>
					<comments>https://michaelsoriano.com/build-a-basic-page-with-salesforce-data-using-heroku-connect-and-nodejs/#comments</comments>
		
		<dc:creator><![CDATA[Michael Soriano]]></dc:creator>
		<pubDate>Thu, 19 Jul 2018 17:58:44 +0000</pubDate>
				<category><![CDATA[Salesforce]]></category>
		<category><![CDATA[Heroku]]></category>
		<category><![CDATA[Heroku Connect]]></category>
		<category><![CDATA[NodeJS]]></category>
		<guid isPermaLink="false">http://michaelsoriano.com/?p=6580</guid>

					<description><![CDATA[<p>This is a tutorial on how to fetch Salesforce Data from an external NodeJS application. To be more specific, we&#8217;re grabbing records in a SF custom object via Heroku Connect. Note that Heroku Connect utilizes an internal Postgres Database, to keep a &#8220;replica&#8221; of the data in Salesforce. Heroku Connect does a &#8220;poll&#8221; of this [&#8230;]</p>
<p>The post <a href="https://michaelsoriano.com/build-a-basic-page-with-salesforce-data-using-heroku-connect-and-nodejs/">Build a Basic Page with Salesforce Data using Heroku Connect and NodeJS</a> appeared first on <a href="https://michaelsoriano.com">Michael Soriano</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>This is a tutorial on how to fetch Salesforce Data from an external NodeJS application. To be more specific, we&#8217;re grabbing records in a SF custom object via Heroku Connect. Note that Heroku Connect utilizes an internal Postgres Database, to keep a &#8220;replica&#8221; of the data in Salesforce. Heroku Connect does a &#8220;poll&#8221; of this data &#8211; keeping both synchronized.</p>



<p>If you haven&#8217;t heard of <a href="https://www.heroku.com">Heroku</a>, head on to their site to learn more. <a href="https://www.heroku.com/connect">Heroku Connect</a> is an add-on to Heroku, which is what makes this all possible. <a href="https://www.heroku.com/postgres">Heroku Postgres</a>, also an add-on &#8211; and their implementation of PostgreSQL. And of course, Salesforce is a well known CRM software &#8211; which is where our data ultimately lives. NodeJS is JavaScript that runs on the server. </p>



<p>We are using Node because it&#8217;s easy to work with &#8211; especially with Heroku.</p>



<p><strong>The Business Case</strong>: Why would you need an &#8220;Interim&#8221; layer? Why go through Postgres first, then Salesforce? Because you certainly can do this. In our case, we have a limited license on the custom objects that we can use. So it makes sense to use Postgres for the majority of the application and use as little custom objects as possible. So designing the application in Postgres, and leave the final read / write in Salesforce makes sense.</p>



<p>Ready to get started? Let&#8217;s begin:</p>



<h3 class="wp-block-heading">1) Create an app in Heroku</h3>



<p>If you haven&#8217;t already done so, sign up for account with Heroku. You can get a free plan &#8211; which is enough to do this tutorial. Once signed up, go to the dashboard and create an app. In our case, we&#8217;re calling it &#8220;basic-api-app&#8221;.</p>



<p><img decoding="async" width="693" height="490" class="alignnone size-full wp-image-6634" src="https://michaelsoriano.com/wp-content/uploads/2018/07/create-app-heroku4.png" alt="create heroku app" srcset="https://michaelsoriano.com/wp-content/uploads/2018/07/create-app-heroku4.png 693w, https://michaelsoriano.com/wp-content/uploads/2018/07/create-app-heroku4-300x212.png 300w" sizes="(max-width: 693px) 100vw, 693px" /></p>



<p>This will spin up a new &#8220;dyno&#8221; and build the necessary elements to do a basic app. Check your project in the browser by clicking &#8220;Open app&#8221;. You should see something like below:</p>



<p><img decoding="async" width="601" height="247" class="alignnone size-full wp-image-6585" src="https://michaelsoriano.com/wp-content/uploads/2018/07/create-app-heroku-2.png" alt="Heroku app" srcset="https://michaelsoriano.com/wp-content/uploads/2018/07/create-app-heroku-2.png 601w, https://michaelsoriano.com/wp-content/uploads/2018/07/create-app-heroku-2-300x123.png 300w" sizes="(max-width: 601px) 100vw, 601px" /><br>Now let&#8217;s continue to the next step &#8211; which is to build our project in locally.</p>



<h3 class="wp-block-heading">2) Build Project Locally</h3>



<p>For building locally, you will need the following items. These are pretty common industry tools, except Heroku CLI. Heroku CLI allows us to interact with our Heroku application using our local terminal.</p>



<ul class="wp-block-list">
<li>Heroku CLI</li>



<li>Git</li>



<li>NodeJS</li>



<li>NPM</li>
</ul>



<p>Let&#8217;s start from an empty directory and initialize Heroku Git. The commands below are listed in order, but is executed one at a time. I just listed them out for brevity.</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">heroku login
git init
heroku git:remote -a basic-api-app</code></pre>



<p>The above logs you in Heroku, initializes Git in the current directory and adds the remote repo as our origin.  Note that your git repo will look like:</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash"><strong>git.heroku.com/your-application.git</strong></code></pre>



<p>Now let&#8217;s grab the starter NodeJS pack from Heroku and add to our project.</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">git clone https://github.com/heroku/node-js-getting-started.git</code></pre>



<p>This will create a folder called &#8220;node-js-getting-started&#8221; inside the current directory. You can simply copy the contents of that folder (except .git) paste it outside.</p>



<p><img decoding="async" width="654" height="301" class="alignnone size-full wp-image-6588" src="https://michaelsoriano.com/wp-content/uploads/2018/07/local-project.png" alt="Local Project" srcset="https://michaelsoriano.com/wp-content/uploads/2018/07/local-project.png 654w, https://michaelsoriano.com/wp-content/uploads/2018/07/local-project-300x138.png 300w" sizes="(max-width: 654px) 100vw, 654px" /></p>



<p><br>Now you can delete of the folder the starter pack came with.</p>



<p>Let&#8217;s go ahead and do our first commit. This adds the files to our remote repository.</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">git add .
git commit -m "first commit"
git push heroku master</code></pre>



<p>Again the above commands are listed &#8211; but should be executed one at a time.</p>



<p>After the push &#8211; you should see that we have our NodeJS application running. Refresh the app url and you should see:</p>



<p><img decoding="async" width="693" height="389" class="alignnone size-full wp-image-6593" src="https://michaelsoriano.com/wp-content/uploads/2018/07/node-js.png" alt="" srcset="https://michaelsoriano.com/wp-content/uploads/2018/07/node-js.png 693w, https://michaelsoriano.com/wp-content/uploads/2018/07/node-js-300x168.png 300w" sizes="(max-width: 693px) 100vw, 693px" /></p>



<p>Let&#8217;s get this running locally. Let&#8217;s do the following commands:</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">npm install express ejs
node index.js</code></pre>



<p>Open up your browser and browse to localhost:5000 &#8211; and you should see the same page that you saw above. Now we&#8217;re ready to move on.</p>



<h3 class="wp-block-heading">3) Create a Custom Object in Salesforce</h3>



<p>If you haven&#8217;t done so, sign up for a .org in <a href="https://www.salesforce.com">Salesforce.com</a>. This will allow you to utilize Salesforce and it&#8217;s many functionalities.</p>



<p>Now in your Salesforce org, let&#8217;s go to S<strong>etup</strong> > Q<strong>uick find, </strong>type &#8220;<strong>Object Manager</strong>&#8220;. Click <strong>Object Manager </strong>from the search results and on the top right of the page, there is a &#8220;<strong>Create</strong>&#8221; button that will allow us to build the object we&#8217;re going to work with our application.</p>



<p><img decoding="async" width="818" height="125" class="alignnone size-full wp-image-6596" src="https://michaelsoriano.com/wp-content/uploads/2018/07/custom-obj.png" alt="" srcset="https://michaelsoriano.com/wp-content/uploads/2018/07/custom-obj.png 818w, https://michaelsoriano.com/wp-content/uploads/2018/07/custom-obj-300x46.png 300w, https://michaelsoriano.com/wp-content/uploads/2018/07/custom-obj-768x117.png 768w" sizes="(max-width: 818px) 100vw, 818px" /><br></p>



<p>Now let&#8217;s create one that&#8217;s called &#8220;<strong>Example</strong>&#8221; (for lack of originality). This will create an object &#8211; with the basic fields.</p>



<p><img decoding="async" width="625" height="446" class="alignnone size-full wp-image-6598" style="border: 1px solid #e5e5e5;" src="https://michaelsoriano.com/wp-content/uploads/2018/07/custom-obj2.png" alt="salesforce - custom object" srcset="https://michaelsoriano.com/wp-content/uploads/2018/07/custom-obj2.png 625w, https://michaelsoriano.com/wp-content/uploads/2018/07/custom-obj2-300x214.png 300w" sizes="(max-width: 625px) 100vw, 625px" /></p>



<p>I also added another field called &#8220;<strong>Description</strong>&#8220;. So our &#8220;Fields and Relationships&#8221; look like below:</p>



<p><img decoding="async" width="625" height="390" class="alignnone size-full wp-image-6600" style="border: 1px solid #e5e5e5;" src="https://michaelsoriano.com/wp-content/uploads/2018/07/custom-obj3.png" alt="salesforce - custom obj" srcset="https://michaelsoriano.com/wp-content/uploads/2018/07/custom-obj3.png 625w, https://michaelsoriano.com/wp-content/uploads/2018/07/custom-obj3-300x187.png 300w" sizes="(max-width: 625px) 100vw, 625px" /></p>



<p>Go back to &#8220;<strong>Quick Find</strong>&#8221; and look for &#8220;<strong>Tab</strong>&#8220;. This will bring us to the &#8220;<strong>Tabs</strong>&#8221; page.</p>



<p>Create a new custom object tab. This will allow us to add test data.</p>



<p><img decoding="async" width="625" height="390" class="alignnone size-full wp-image-6601" style="border: 1px solid #e5e5e5;" src="https://michaelsoriano.com/wp-content/uploads/2018/07/custom-obj4.png" alt="Custom Tab" srcset="https://michaelsoriano.com/wp-content/uploads/2018/07/custom-obj4.png 625w, https://michaelsoriano.com/wp-content/uploads/2018/07/custom-obj4-300x187.png 300w" sizes="(max-width: 625px) 100vw, 625px" /></p>



<p>Now let&#8217;s add some test data. Get out of &#8220;<strong>Setup</strong>&#8221; and click on the new tab you just created. Add new test data and we should have something like below.</p>



<p><img decoding="async" width="449" height="239" class="alignnone size-full wp-image-6638" style="border: 1px solid #e5e5e5;" src="https://michaelsoriano.com/wp-content/uploads/2018/07/example-data.png" alt="Example data" srcset="https://michaelsoriano.com/wp-content/uploads/2018/07/example-data.png 449w, https://michaelsoriano.com/wp-content/uploads/2018/07/example-data-300x160.png 300w" sizes="(max-width: 449px) 100vw, 449px" /></p>



<p>Now we&#8217;re ready for the next part, Heroku Connect.</p>



<h3 class="wp-block-heading">4) Heroku Connect</h3>



<p>In Heroku, in your app&#8217;s dashboard, look for the spot where it says &#8220;<strong>Add-ons</strong>&#8220;. Type in &#8220;<strong>Connect</strong>&#8221; and you should see &#8220;<strong>Heroku Connect</strong>&#8221; from the results.</p>



<p><img decoding="async" width="498" height="386" class="alignnone size-full wp-image-6603" src="https://michaelsoriano.com/wp-content/uploads/2018/07/heroku-connect1.png" alt="Heroku connect" srcset="https://michaelsoriano.com/wp-content/uploads/2018/07/heroku-connect1.png 498w, https://michaelsoriano.com/wp-content/uploads/2018/07/heroku-connect1-300x233.png 300w" sizes="(max-width: 498px) 100vw, 498px" /></p>



<p>Click the &#8220;<strong>Provision</strong>&#8221; once the modal pops up. You can simply choose the &#8220;<strong>Hobby Dev-Free</strong>&#8221; plan for now.<br></p>



<p><img decoding="async" width="574" height="434" class="alignnone size-full wp-image-6606" src="https://michaelsoriano.com/wp-content/uploads/2018/07/heroku-db.png" alt="heroku postgres" srcset="https://michaelsoriano.com/wp-content/uploads/2018/07/heroku-db.png 574w, https://michaelsoriano.com/wp-content/uploads/2018/07/heroku-db-300x227.png 300w" sizes="(max-width: 574px) 100vw, 574px" /></p>



<p>After success, you should see this in your Heroku dashboard:<br></p>



<p><img decoding="async" width="443" height="321" class="alignnone size-full wp-image-6605" src="https://michaelsoriano.com/wp-content/uploads/2018/07/heroku-connect2.png" alt="heroku connect - success" srcset="https://michaelsoriano.com/wp-content/uploads/2018/07/heroku-connect2.png 443w, https://michaelsoriano.com/wp-content/uploads/2018/07/heroku-connect2-300x217.png 300w" sizes="(max-width: 443px) 100vw, 443px" /></p>



<p>You also need the Heroku Postgres  add on. Do the same steps above, but for <strong>Heroku Postgres</strong>. When everything is in place, now we can continue to setup a connection. Click on &#8220;<strong>Setup Connection</strong>&#8220;:</p>



<p><img decoding="async" width="474" height="309" class="alignnone size-full wp-image-6611" style="border: 1px solid #e5e5e5;" src="https://michaelsoriano.com/wp-content/uploads/2018/07/setup-connection.png" alt="setup connection" srcset="https://michaelsoriano.com/wp-content/uploads/2018/07/setup-connection.png 474w, https://michaelsoriano.com/wp-content/uploads/2018/07/setup-connection-300x196.png 300w" sizes="(max-width: 474px) 100vw, 474px" /></p>



<p>The next page simply verifies the database to use, and the schema name for your connection. Simply click &#8220;<strong>Next</strong>&#8220;.</p>



<p><img decoding="async" width="783" height="355" class="alignnone size-full wp-image-6610" style="border: 1px solid #e5e5e5;" src="https://michaelsoriano.com/wp-content/uploads/2018/07/setup-db.png" alt="setup db" srcset="https://michaelsoriano.com/wp-content/uploads/2018/07/setup-db.png 783w, https://michaelsoriano.com/wp-content/uploads/2018/07/setup-db-300x136.png 300w, https://michaelsoriano.com/wp-content/uploads/2018/07/setup-db-768x348.png 768w" sizes="(max-width: 783px) 100vw, 783px" /><br></p>



<p>The next screen initializes the authorization part. Heroku will attempt to connect to your Salesforce. Select &#8220;Sandbox&#8221; and follow the prompts.</p>



<p><img decoding="async" width="783" height="355" class="alignnone size-full wp-image-6609" style="border: 1px solid #e5e5e5;" src="https://michaelsoriano.com/wp-content/uploads/2018/07/setup-oauth.png" alt="Salesforce OAuth" srcset="https://michaelsoriano.com/wp-content/uploads/2018/07/setup-oauth.png 783w, https://michaelsoriano.com/wp-content/uploads/2018/07/setup-oauth-300x136.png 300w, https://michaelsoriano.com/wp-content/uploads/2018/07/setup-oauth-768x348.png 768w" sizes="(max-width: 783px) 100vw, 783px" /></p>



<p>When you get to the login &#8211; add your credentials.</p>



<p><img decoding="async" width="447" height="484" class="alignnone size-full wp-image-6614" src="https://michaelsoriano.com/wp-content/uploads/2018/07/oauth-login.png" alt="salesforce login" srcset="https://michaelsoriano.com/wp-content/uploads/2018/07/oauth-login.png 447w, https://michaelsoriano.com/wp-content/uploads/2018/07/oauth-login-277x300.png 277w" sizes="(max-width: 447px) 100vw, 447px" /></p>



<p>Once this process is complete &#8211; we should be good to go. Now we can do the real work.<br>Let&#8217;s create our first &#8220;<strong>Mapping</strong>&#8220;. From the list of Salesforce objects &#8211; choose &#8220;<strong>Example__c</strong>&#8221; &#8211; the custom object:</p>



<p><img decoding="async" width="756" height="443" class="alignnone size-full wp-image-6613" style="border: 1px solid #e5e5e5;" src="https://michaelsoriano.com/wp-content/uploads/2018/07/pick-object.png" alt="pick object" srcset="https://michaelsoriano.com/wp-content/uploads/2018/07/pick-object.png 756w, https://michaelsoriano.com/wp-content/uploads/2018/07/pick-object-300x176.png 300w" sizes="(max-width: 756px) 100vw, 756px" /></p>



<p>Besides the basic fields &#8211; let&#8217;s make sure we have the two fields that we need: <strong>Name</strong> and <strong>Description__c</strong>. At the moment, we&#8217;ll just focus on &#8220;<strong>Salesforce -> Database</strong>&#8221; part. Let&#8217;s get to the bi-directional style at a later time.</p>



<p><img decoding="async" width="700" height="546" class="alignnone size-full wp-image-6616" style="border: 1px solid #e5e5e5;" src="https://michaelsoriano.com/wp-content/uploads/2018/07/edit-mapping.png" alt="edit mapping" srcset="https://michaelsoriano.com/wp-content/uploads/2018/07/edit-mapping.png 700w, https://michaelsoriano.com/wp-content/uploads/2018/07/edit-mapping-300x234.png 300w" sizes="(max-width: 700px) 100vw, 700px" /><br></p>



<p>If all goes well, we should see the screen below. This shows that we&#8217;re all &#8220;<strong>Synced</strong>&#8220;.</p>



<p>This means that the columns in our custom object, has been successfully &#8220;<strong>mapped</strong>&#8221; to our Postgres table. It also shows that the records in Salesforce has been copied over.</p>



<p><img decoding="async" width="682" height="461" class="alignnone size-full wp-image-6619" style="border: 1px solid #e5e5e5;" src="https://michaelsoriano.com/wp-content/uploads/2018/07/heroku-data-synced.png" alt="heroku - data synced" srcset="https://michaelsoriano.com/wp-content/uploads/2018/07/heroku-data-synced.png 682w, https://michaelsoriano.com/wp-content/uploads/2018/07/heroku-data-synced-300x203.png 300w" sizes="(max-width: 682px) 100vw, 682px" /></p>



<p>To prove this, click on the &#8220;Explorer&#8221; tab, and you should see our dummy records that we&#8217;ve entered a while ago.</p>



<p><img decoding="async" width="649" height="370" class="alignnone size-full wp-image-6625" style="border: 1px solid #e5e5e5;" src="https://michaelsoriano.com/wp-content/uploads/2018/07/heroku-explorer.png" alt="Heroku - explorer" srcset="https://michaelsoriano.com/wp-content/uploads/2018/07/heroku-explorer.png 649w, https://michaelsoriano.com/wp-content/uploads/2018/07/heroku-explorer-300x171.png 300w" sizes="(max-width: 649px) 100vw, 649px" /></p>



<p>This brings us to the final step. Which is writing the code that pulls this data from Heroku.</p>



<h3 class="wp-block-heading">5) Access the data via NodeJS</h3>



<p>First, let&#8217;s grab the &#8220;<strong>DATABASE_URL</strong>&#8221; from our application. You can find this under your app&#8217;s <strong>Settings</strong> > &#8220;<strong>Config Vars</strong>&#8221; section. Copy this value. </p>



<p>Go back to your local setup. Open the folder in your favorite text editor. Once that&#8217;s up, create a &#8220;<strong>.env</strong>&#8221; file. Quick note: a <strong>.env</strong> file is a configuration file that stays in your local setup. It is not committed to Git, and is only honored when your localhost is running (using the command: <strong>heroku local</strong>).</p>



<p>Open this file and add the key &#8220;<strong>DATABASE_URL</strong>&#8221; , with the value that you copied previously from your heroku app. </p>



<p>With this in place, we can continue to work with our application &#8211; with the Postgres database we provisioned in Heroku. </p>



<p>Let&#8217;s add a custom route in Express. Open &#8220;<strong>index.js</strong>&#8221; and add the code below:</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">const { Client } = require('pg');
express.get('/db', (req, res) =&gt; {
  //rest of the code here...
})</code></pre>



<p>This simply sets up a page we can access via the &#8220;/<strong>db</strong>&#8221; route. We&#8217;re also requiring the module &#8220;<strong>pg</strong>&#8221; &#8211; which we need to install via npm:</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">npm install pg</code></pre>



<p>Now that our pg module is installed, let&#8217;s add some code inside our route handler:</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">var dbOpts = {
      connectionString: process.env.DATABASE_URL,
      ssl : true
    }
const client = new Client(dbOpts);
client.connect();
client.query('SELECT id, name, Description__c FROM salesforce.example__c;', (err, dbRes) =&gt; {
      if (err) throw err;
      res.render('pages/db',{
        results : dbRes.rows
      });
      client.end();
    });
client.end();</code></pre>



<p>The code above sets up the options for our Postgres client. We connect, then run a simple &#8220;<strong>SELECT</strong>&#8221; statement. Inside the query function, we pass the result &#8211; as an object to the &#8220;<strong>db.ejs</strong>&#8221; temlplate that we have. Finally, we close the connection.</p>



<p>Note that for other database interactions such as INSERT, UPDATE, DELETE &#8211; consult with the <a href="https://node-postgres.com/">pg module documentation</a>.</p>



<p>Open <strong>db.ejs</strong> inside the pages folder and modify the code that is inside the DIV.container:</p>



<pre class="wp-block-code"><code lang="markup" class="language-markup">&lt;ul&gt;
    &lt;% results.forEach(function(r) { %&gt;
        &lt;li&gt;
            &lt;strong&gt;&lt;%= r.name %&gt;&lt;/strong&gt;
            &lt;small&gt;&lt;%= r.description__c %&gt;&lt;/small&gt;
        &lt;/li&gt;
    &lt;% }); %&gt;
&lt;/ul&gt;</code></pre>



<p>The above is a simple markup that loops through each of the items in our table and spits it out.<br>Finally, let&#8217;s run our code. Open a terminal and run:</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">heroku local</code></pre>



<p>This loads the local .env file and starts up our application on the specified port. Open up a browser and navigate to localhost:5000/db &#8211; and you should see our page with the data:</p>



<p><img decoding="async" width="781" height="276" class="alignnone size-full wp-image-6631" src="https://michaelsoriano.com/wp-content/uploads/2018/07/node-db.png" alt="node js page" srcset="https://michaelsoriano.com/wp-content/uploads/2018/07/node-db.png 781w, https://michaelsoriano.com/wp-content/uploads/2018/07/node-db-300x106.png 300w, https://michaelsoriano.com/wp-content/uploads/2018/07/node-db-768x271.png 768w" sizes="(max-width: 781px) 100vw, 781px" /></p>



<p>Finally, let&#8217;s push the code to Heroku:</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">git add .
git commit -m "added more files"
git push heroku master</code></pre>



<h3 class="wp-block-heading">Conclusion</h3>



<p>So there you go &#8211; we have a basic page that can interact with Salesforce data via Heroku. As you can see, Heroku Connect does the hard work of building a Postgres database and mapping it with Salesforce.  </p>



<p>Once this is setup &#8211; all you need to worry about is your application and the Postgres database. The rest is done by Heroku.</p>
<p>The post <a href="https://michaelsoriano.com/build-a-basic-page-with-salesforce-data-using-heroku-connect-and-nodejs/">Build a Basic Page with Salesforce Data using Heroku Connect and NodeJS</a> appeared first on <a href="https://michaelsoriano.com">Michael Soriano</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://michaelsoriano.com/build-a-basic-page-with-salesforce-data-using-heroku-connect-and-nodejs/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Let&#8217;s Build an AutoSuggest Lightning Component with Google Places API</title>
		<link>https://michaelsoriano.com/lightning-component-google-places/</link>
					<comments>https://michaelsoriano.com/lightning-component-google-places/#comments</comments>
		
		<dc:creator><![CDATA[Michael Soriano]]></dc:creator>
		<pubDate>Fri, 11 May 2018 22:18:19 +0000</pubDate>
				<category><![CDATA[Salesforce]]></category>
		<category><![CDATA[Aura]]></category>
		<guid isPermaLink="false">http://michaelsoriano.com/?p=6511</guid>

					<description><![CDATA[<p>I had the challenge of building an input form that brings up a list of cities as you type. One that has the coordinates of each city &#8211; because I&#8217;ll need to enter that into a map. An &#8220;auto-suggest&#8221; or &#8220;auto-complete&#8221; city input &#8211; inside a custom form inside Salesforce. It turns out, that it [&#8230;]</p>
<p>The post <a href="https://michaelsoriano.com/lightning-component-google-places/">Let&#8217;s Build an AutoSuggest Lightning Component with Google Places API</a> appeared first on <a href="https://michaelsoriano.com">Michael Soriano</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>I had the challenge of building an input form that brings up a list of cities as you type. One that has the coordinates of each city &#8211; because I&#8217;ll need to enter that into a map. An &#8220;auto-suggest&#8221; or &#8220;auto-complete&#8221; city input &#8211; inside a custom form inside Salesforce. It turns out, that it wasn&#8217;t so bad.</p>



<p>We&#8217;re using <a href="https://developers.google.com/places/">Google Places</a> for our API and Lightning Components for our Front End. If you&#8217;re not familiar with Lightning, check their <a href="https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/intro_framework.htm">documentation</a>.</p>



<p>Our component will look like below.</p>



<p><img decoding="async" width="617" height="214" class="alignnone size-full wp-image-6512" src="https://michaelsoriano.com/wp-content/uploads/2018/04/auto-suggest.png" alt="lightning input autosuggest" srcset="https://michaelsoriano.com/wp-content/uploads/2018/04/auto-suggest.png 617w, https://michaelsoriano.com/wp-content/uploads/2018/04/auto-suggest-300x104.png 300w" sizes="(max-width: 617px) 100vw, 617px" /></p>



<p>Ready to start coding? Let&#8217;s start.</p>



<h3 class="wp-block-heading" id="api-setup">API Setup</h3>



<p>Let&#8217;s get Google going. Remember, each time a user type a character &#8211; it will ping Google for suggestions. Also, the suggestions does not contain coordinates for each item, so we will need to ping the API as soon as the user selects a place.</p>



<p>I&#8217;m going to assume that you know how to get an API key from your Google account. If not, here is their <a href="https://developers.google.com/places/web-service/intro">API documentation</a>.</p>



<p>The first part is getting the suggestions. Below is the URL that we need for that:</p>



<p><strong>https://maps.googleapis.com/maps/api/place/autocomplete/json?input=TERM&amp;key=YOURKEY</strong></p>



<p>Looking at the above, we&#8217;re passing in what the user is typing where it says &#8220;TERM&#8221;.<br>The second part is when the user selects an item:</p>



<p><strong>https://maps.googleapis.com/maps/api/place/details/json?placeid=PLACEID&amp;key=YOURKEY</strong></p>



<p>The above shows a &#8220;placeid&#8221; parameter that we get from each suggestion. So when the user clicks &#8211; we pass the id to the above URL.</p>



<p>Now that we have our Places API setup. Let&#8217;s move forward to our Salesforce code.</p>



<h3 class="wp-block-heading" id="build-the-apex-class">Build the Apex Class</h3>



<p>One thing to note is that our Lighting components cannot reach out to Places API directly. Google doesn&#8217;t allow CORS to their endpoints &#8211; so we simply cannot do this. Nor would we want to &#8211; because if we do this via JavaScript &#8211; we will be exposing our keys. So we need the server to do the calls. In Salesforce, we use Apex.</p>



<p>We also have to add &#8220;maps.googleapis.com&#8221; to the remote site settings in Salesforce. To do this, go to &#8220;Setup&#8221; > &#8220;Security&#8221; > &#8220;Remote Site Settings&#8221;.</p>



<p>Click on &#8220;New Remote Site&#8221; and add the required fields:</p>



<p><img decoding="async" width="565" height="489" class="alignnone size-full wp-image-6551" src="https://michaelsoriano.com/wp-content/uploads/2018/05/remote-site-settings.png" alt="Remote site settings - Salesflorce" srcset="https://michaelsoriano.com/wp-content/uploads/2018/05/remote-site-settings.png 565w, https://michaelsoriano.com/wp-content/uploads/2018/05/remote-site-settings-300x260.png 300w" sizes="(max-width: 565px) 100vw, 565px" /></p>



<p>Now, let&#8217;s create our Apex Class. Copy the code below and add it to your Class:</p>



<pre class="wp-block-code"><code lang="java" class="language-java">@AuraEnabled
	public static string getSuggestions(String input) {
	    String url = 'https://maps.googleapis.com/maps/api/place/autocomplete/json?'
	            + 'input=' + EncodingUtil.urlEncode(input, 'UTF-8')
	            + '&amp;types=(cities)' + getKey();
	    String response = getResponse(url);
	    return response;
	}
@AuraEnabled
	public static string getPlaceDetails(String placeId) {
     	String url = 'https://maps.googleapis.com/maps/api/place/details/json?'
	            + 'placeid=' + EncodingUtil.urlEncode(placeId, 'UTF-8')
	            + getKey();
	    String response = getResponse(url);
	    return response;
	}
	public static string getResponse(string strURL){
		Http h = new Http();
		HttpRequest req = new HttpRequest();
		HttpResponse res = new HttpResponse();
		req.setMethod('GET');
		req.setEndpoint(strURL);
		req.setTimeout(120000);
		res = h.send(req);
		String responseBody = res.getBody();
		return responseBody;
	}
	public static string getKey(){
		string key = 'xxxxxxxxxxxxx';
		string output = '&amp;key=' + key;
		return output;
	}</code></pre>



<p>Note the two methods that have <strong>@AuraEnabled</strong>: getSuggestions() and getPlaceDetails(). These are the two endpoints we will be calling from our JavaScript in our Lightning component. Both methods are quite explanatory, they simply accept parameters from our front end, go out to Google and return the results.</p>



<p>Don&#8217;t forget to add your API key to the method getKey().</p>



<p>Let&#8217;s move on.</p>



<h3 class="wp-block-heading" id="our-component">Our&nbsp;Component</h3>



<p>The component (.cmp file) will need a few things. First, we need a couple of attributes to hold our values. One for location and one called &#8220;predictions&#8221;. The location is the value that will be in our input, while the predictions is what will show directly beneath it &#8211; in an unordered list. Note that this is what comes back from our API.  So add that first to your component.</p>



<pre class="wp-block-code"><code lang="markup" class="language-markup">&lt;aura:attribute name="location" type="string" default=""/>
&lt;aura:attribute name="predictions" type="List" default="[]"/></code></pre>



<p>We&#8217;re using &#8220;<strong>lightning:input</strong>&#8221; for our form field. We add a label, name, an aura:id, a value and an onchange attribute. The label and name is pretty straightforward, the aura:id &#8211; is simply a way for us to reference it in our controller.</p>



<p>The <strong>value</strong> &#8211; binds the input to our attribute &#8220;location&#8221;. Which we show as &#8220;<strong>v.location</strong>&#8220;.</p>



<p>The <strong>onchange &#8211; </strong>we&#8217;re attaching to a function in our controller named <strong>getCities(), </strong>which we refer to as &#8220;<strong>c.getCities</strong>&#8220;.</p>



<pre class="wp-block-code"><code lang="markup" class="language-markup">&lt;lightning:input label="Location"
                        name="location"
                        aura:id="location"
                        value="{!v.location}"
                        onchange="{!c.getCities}" /></code></pre>



<p>We&#8217;re using an unordered list for our suggestions. So we use the code below:</p>



<pre class="wp-block-code"><code lang="markup" class="language-markup">&lt;aura:if isTrue="{!v.predictions.length > 0}">
 	&lt;ul class="city_predictions">
		&lt;aura:iteration items="{!v.predictions}" var="prediction">
			&lt;li class="slds-listbox__item">
				&lt;a onclick="{!c.getCityDetails}" data-placeid="{!prediction.place_id}">{!prediction.description}&lt;/a>
			&lt;/li>
		&lt;/aura:iteration>
	&lt;/ul>
&lt;/aura:if></code></pre>



<p>Notice we wrap it an &#8220;<strong>aura:if</strong>&#8221;  &#8211; which determines if our predictions object has more than zero length. Remember, predictions is coming straight from the API.</p>



<p>Then we have an &#8220;<strong>aura:iteration</strong>&#8221; for each prediction to show up in a list item > anchor tag. Each anchor tag has an &#8220;onclick&#8221; (which we&#8217;re attaching to getCityDetails()) and a &#8220;data-placeid&#8221; (I&#8217;ll explain later).</p>



<h3 class="wp-block-heading" id="the-controller">The Controller</h3>



<p>So remember in our component we have 2 methods: getCities() and getCityDetails()? Those both go in our controller.</p>



<p>Our <strong>getCities() </strong>method is called every time we change the input field. Meaning &#8211; every time we type a letter, it calls this method.</p>



<p>First it sets up an object called &#8220;<strong>params</strong>&#8220;, which has one item in it called &#8220;<strong>input</strong>&#8220;. This is what we&#8217;re sending our Apex class through the use of <strong>helper.callServer()</strong>. This helper is explained in my previous post &#8220;<a href="https://michaelsoriano.com/call-apex-from-lightning-components/">Call Apex from Lightning</a>&#8220;. Once our Apex responds with some suggestions &#8211; we parse it through JSON.parse() and set it to our component attribute called &#8220;predictions&#8221;.</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">getCities : function(component, event, helper){
	var params = {
	  "input" : component.get('v.location')
	}
	helper.callServer(component,"c.getSuggestions",function(response){
		var resp = JSON.parse(response);
		console.log(resp.predictions);
		component.set('v.predictions',resp.predictions);
	},params);
}</code></pre>



<p>So our UL of suggestions will only populate if there&#8217;s a response from the server.</p>



<p>Finally, <strong>getCityDetails()</strong> get&#8217;s triggered when we choose an item from our UL (or click the anchor tag).<br>Remember the &#8220;data-placeid&#8221; attribute that we have for each anchor tag? This is where we will need it.</p>



<p>We grab the value of &#8220;data-placeid&#8221; (which is the Place Id required for our API) through the event.currentTarget. We then create the &#8220;params&#8221; object like we did above.</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">getCityDetails : function(component, event, helper){
	var selectedItem = event.currentTarget;
        var placeid = selectedItem.dataset.placeid;
	var params = {
	   "placeId" : placeid
	}
	helper.callServer(component,"c.getPlaceDetails",function(response){
		var placeDetails = JSON.parse(response);
		component.set('v.location',placeDetails.result.name);
		component.set('v.predictions',[]);
	},params);
}</code></pre>



<p>We then do a <strong>helper.callServer() </strong>and when finished, we parse then set the v.location (the input value) and v.predictions back to empty.</p>



<p>I specifically needed the coordinates for the selected location, which can easily be grabbed from the response. You can do something similar.</p>



<h3 class="wp-block-heading" id="the-final-product">The Final Product:</h3>



<p>Below is a short screengrab of the final output. The <strong>lightning:input</strong> makes our field look better than just a regular input. Also, this is a &#8220;barebones&#8221; solution for an auto suggest field. You can greatly enhance by adding icons, additional description for each place, maybe some more events (like on tab, enter etc).</p>



<p><br><img decoding="async" width="639" height="324" class="alignnone size-full wp-image-6514" style="margin-top: -15px;" src="https://michaelsoriano.com/wp-content/uploads/2018/04/auto-suggest.gif" alt="Lightning Auto Suggest"></p>
<p>The post <a href="https://michaelsoriano.com/lightning-component-google-places/">Let&#8217;s Build an AutoSuggest Lightning Component with Google Places API</a> appeared first on <a href="https://michaelsoriano.com">Michael Soriano</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://michaelsoriano.com/lightning-component-google-places/feed/</wfw:commentRss>
			<slash:comments>14</slash:comments>
		
		
			</item>
		<item>
		<title>Call Apex from Lightning components</title>
		<link>https://michaelsoriano.com/call-apex-from-lightning-components/</link>
					<comments>https://michaelsoriano.com/call-apex-from-lightning-components/#comments</comments>
		
		<dc:creator><![CDATA[Michael Soriano]]></dc:creator>
		<pubDate>Mon, 07 May 2018 17:20:45 +0000</pubDate>
				<category><![CDATA[Salesforce]]></category>
		<category><![CDATA[Aura]]></category>
		<guid isPermaLink="false">http://michaelsoriano.com/?p=6523</guid>

					<description><![CDATA[<p>I&#8217;ve decided to do some write up on Salesforce &#8211; especially Lightning development. Lightning is basically Salesforce&#8217;s proprietary JavaScript and CSS Framework bundled into one. It&#8217;s a component-based system, mobile friendly, with the power of a server side language (Apex), just in case you need it. In the following tutorials, you might see a &#8220;helper.callServer()&#8221; [&#8230;]</p>
<p>The post <a href="https://michaelsoriano.com/call-apex-from-lightning-components/">Call Apex from Lightning components</a> appeared first on <a href="https://michaelsoriano.com">Michael Soriano</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>I&#8217;ve decided to do some write up on Salesforce &#8211; especially Lightning development. <a href="https://www.lightningdesignsystem.com">Lightning</a> is basically Salesforce&#8217;s proprietary JavaScript and CSS Framework bundled into one. It&#8217;s a component-based system, mobile friendly, with the power of a server side language (Apex), just in case you need it.</p>



<figure class="wp-block-image size-full"><img decoding="async" width="810" height="405" src="https://michaelsoriano.com/wp-content/uploads/2022/07/lighting-web-components.png" alt="lightning web components" class="wp-image-7767" srcset="https://michaelsoriano.com/wp-content/uploads/2022/07/lighting-web-components.png 810w, https://michaelsoriano.com/wp-content/uploads/2022/07/lighting-web-components-300x150.png 300w, https://michaelsoriano.com/wp-content/uploads/2022/07/lighting-web-components-768x384.png 768w" sizes="(max-width: 810px) 100vw, 810px" /></figure>



<p>In the following tutorials, you might see a &#8220;<strong>helper.callServer()</strong>&#8221; method &#8211; which I&#8217;m outlining below:</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">callServer : function(component,method,callback,params) {
        var action = component.get(method);
        if (params) {
            action.setParams(params);
        }
        action.setCallback(this,function(response) {
            var state = response.getState();
            if (state === "SUCCESS") {
                // pass returned value to callback function
                callback.call(this,response.getReturnValue());
            } else if (state === "ERROR") {
                // generic error handler
                var errors = response.getError();
                if (errors) {
                    console.log("Errors", errors);
                    if (errors[0] &amp;&amp; errors[0].message) {
                        throw new Error("Error" + errors[0].message);
                    }
                } else {
                    throw new Error("Unknown Error");
                }
            }
        });
        $A.enqueueAction(action);
    }</code></pre>



<p>If you&#8217;re ever going to do some kind of call to an Apex class &#8211; this is a must have in your helper. Think of it as sort of like jQuery&#8217;s $.ajax() method &#8211; but limited to a specific class.</p>



<p>Salesforce has the same exact code in this <a href="https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/controllers_server_actions_call.htm">doc</a>&nbsp;with some explanation, but I wanted to write it up in my own words.&nbsp;Let&#8217;s break it down below.</p>



<p>As mentioned, this is what we need to call an Apex class from our components. It is basically a wrapper to an&nbsp;<a href="https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest">XMLHttpRequest</a>, along with other utilities to make our JavaScript easier.</p>



<p>Again, components are front end code &#8211; Apex sits in the server. This method is the communication between the two.</p>



<h3 class="wp-block-heading">Set up Apex</h3>



<p>First, you declare a class. This is done in our .cmp (component) file, way at the top &#8211; it looks like below:</p>



<p><strong>&lt;aura:component implements=&#8221;&#8230;&#8221; controller=&#8221;MyClass&#8221;&gt;</strong></p>



<p>Now we&#8217;re set up with an Apex class called &#8220;MyClass&#8221;. Let&#8217;s build that class, with a method called &#8220;doSomething()&#8221;:</p>



<pre class="wp-block-code"><code lang="java" class="language-java">public with sharing class MyClass{
   @auraEnabled
   public static string doSomething(String input) {
      return input
   }
}</code></pre>



<p>Note the &#8220;@auraEnabled&#8221; declaration. This allows us to access it from our JavaScript.</p>



<p>With the our helper in place, all we need to do in our controller will be something like below:</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">helper.callServer(component,"c.doSomething",function(response){
    //INSIDE OUR CALLBACK
    console.log(response) //RESPONSE FROM OUR APEX METHOD
},{})</code></pre>



<p>You see, our helper had arguments that looked like below:</p>



<p><strong>callServer : function(component,method,callback,params) {&#8230;</strong></p>



<p>Which is what we&#8217;re doing in our controller. The second parameter &#8220;c.doSomething&#8221; &#8211; is the method in our Apex class. The 3rd parameter &#8220;callback&#8221; &#8211; is an anonymous function that get&#8217;s triggered through &#8220;.apply()&#8221; in our helper. This is executed when our Ajax call finishes. And we&#8217;ll have access to the response.</p>



<h3 class="wp-block-heading">Sending Parameters</h3>



<p>You can send information to your Apex class by setting an object to the last parameter called &#8220;params&#8221;. In our example above, we&#8217;re simply passing an empty object &#8220;{}&#8221;. But in reality, you will most likely send something to the server.</p>



<p>Our method &#8220;doSomething&#8221; is expecting a string called &#8220;input&#8221;.</p>



<p>The object we can pass will look like below:</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">{
  "input" : "somevalue"
}</code></pre>



<p>Notice the key &#8220;input&#8221; must match our server variable &#8220;input&#8221;.</p>



<p>If you would like to pass another value, simply add another key:</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">{
  "input" : "somevalue",
  "input2" : "somevalue2"
}</code></pre>



<p>In our doSomething method:</p>



<p><strong>doSomething(String input, String input2)</strong></p>



<p>You can also pass multiple values as a JSON string, so in your controller:</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">var str = JSON.stringify({"input1":"somevalue","input2":"somevalue2"});
var params = {"strsRecord" : str};
helper.callServer(component,"c.doSomething",function(){}, params);</code></pre>



<p>In your Apex class:</p>



<pre class="wp-block-code"><code class="">doSomething(strsRecord){
   List st = JSON.deserialize(strsRecord);
   System.debug('Here is the params:' +st);</code></pre>



<h3 class="wp-block-heading">&#8220;Promise&#8221; Style</h3>



<p>In JavaScript, a <a href="https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-promise-27fc71e77261">promise</a> is &#8220;<em>an object that may produce a single value some time in the future</em>&#8220;. So our helper above is a perfect example of this. Let&#8217;s rewrite it using a promise, so we can use it more efficiently, and elegantly.</p>



<p>By this, I mean avoiding &#8220;callback&#8221; hell. See, callbacks are okay if we&#8217;re dealing with a single call. But if we were to make multiple nested calls (especially one that needs relies on the first response etc), it gets ugly real fast like below:&nbsp;</p>



<p><strong>Callback hell:</strong></p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">helper.callServer(component,"c.doSomething1",function(response1){
     helper.callServer(component,"c.doSomething2",function(response2){
         helper.callServer(component,"c.doSomething3",function(response3){
               //THIS GETS UGLY...
          },{})
     },{})
},{})</code></pre>



<p>So let&#8217;s convert it to use a JavaScript promise instead: </p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">callServer : function(component,method,params) {     //PROMISE BASED
        var promiseObj = new Promise(
            function(resolve, reject){
                var action = component.get(method);
                if (params) {
                    action.setParams(params);
                }
                action.setCallback(this,function(response) {
                    var state = response.getState();
                    if (state === "SUCCESS") {
                        var data = response.getReturnValue();
                        resolve(data)
                    } else if (state === "ERROR") {
                        var errors = response.getError();
                        console.log(errors);
                        reject(errors);
                    }
                });
                $A.enqueueAction(action);
            }
        );
        return promiseObj;
    }</code></pre>



<p>As you can see above, there are no more callbacks being passed. All we need are the 3 parameters: &#8220;component&#8221;, &#8220;method&#8221; and &#8220;params&#8221;. </p>



<p>Now we can use this like below:</p>



<pre class="wp-block-code"><code class="">helper.callServer(component,"c.doSomething",{}).then(function(response){
   console.log(response)
})</code></pre>



<p>You see the use of &#8220;.then()&#8221;. We&#8217;re no longer restricted to a single callback function we were previously. We can even use multiple .then() methods all over our code:</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">var ajax = helper.callServer(component,"c.doSomething",{});
//first .then()
ajax.then(function(response){
   console.log('do something here');
})
//second.then()
ajax.then(function(response){
   console.log('do more stuff here');
})</code></pre>



<p>We can also chain Promise methods like so: </p>



<pre class="wp-block-code"><code class="">var ajax = helper.callServer(component,"c.doSomething",{});
ajax.then(function(response){
   console.log(response);
}).catch(function(error){
   console.log(error)
}).finally(function(){
   console.log('this always runs')
})</code></pre>



<p>As you can see, the &#8220;Promise&#8221; style of the helper can help you write more efficient code. </p>



<p>So keep this in your Lightning helper, in order to communicate with Apex. Its almost always guaranteed to be used at least once in your Salesforce applications. </p>
<p>The post <a href="https://michaelsoriano.com/call-apex-from-lightning-components/">Call Apex from Lightning components</a> appeared first on <a href="https://michaelsoriano.com">Michael Soriano</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://michaelsoriano.com/call-apex-from-lightning-components/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
	</channel>
</rss>
