When Salesforce is life!

Month: April 2019

Salesforce DX Setup – Everything You need to Know

Let’s talk about a great new addition of the Spring’19 platform release to the
Salesforce Dev world, the Lightning Web Components framework, with our guest blogger Priscilla Sharon, Salesforce Business Solution Executive for DemandBlue.

DemandBlue is in the business of helping its customers maximize their Salesforce investment through predictable outcomes. As we thrive in an era of cloud-based Infrastructure, Platform and Software services, DemandBlue has pioneered “Service-as-a-Service” through a value-based On Demand Service model that drives bottom-line results. They foster innovation through “Continuous Engagement and On Demand Execution” that offers their customers Speed, Value and Success to achieve their current and future business objectives.


Salesforce DX Setup – Since inception, one of Salesforce’s core philosophies and the Big Idea has been to make building easy. Software should not be complex to install, set up, or customize. In fact, you shouldn’t have to even install software – it should be available to you at the click of a button – This declarative approach of Salesforce brought an end to complex and traditional methods of software development that even non-tech executives including business analysts and managers could slickly build line-of-business applications in a few clicks. However, while Salesforce was democratizing application development through clicks-not-code approach and ushering in the era of citizen programmer, there were other players who were strengthening their appeal to the traditional developer. With nuanced business requirements, modeling complex domains require more flexibility than clicks-not-code affords. Traditional methods of development weren’t dead after all.

As a result, Salesforce’s marketing and development efforts wanted to cater to the traditional developer with the introduction of Salesforce DX, a revolutionary product in the Salesforce App Cloud that allows users to develop and manage Salesforce apps throughout the entire platform in a more direct and efficient way. Used primarily by developers, Salesforce DX setup enables users to have true version control that allows them to have a better control over collaboration, auditing, disaster control and more.

Take a deeper dive into the comprehensive blog that gives you in-depth insights on how you can enable Salesforce DX environment and truly maximize its unique benefits.

Your 12 Step Salesforce DX Setup Guide

1.     Set up your project

Salesforce DX introduces a new project structure for your org’s metadata (code and configuration), your org templates, your sample data, and all your team’s tests. Store these items in a version control system (VCS) to bring consistency to your team’s development processes. Retrieve the contents of your team’s repository when you’re ready to develop a new feature.

2.     Salesforce DX Setup – Authorize the Developer Hub org for the project

During Salesforce DX setup, the Dev Hub org enables you to create, delete, and manage your Salesforce scratch orgs. After you set up your project on your local machine, you authorize with the Dev Hub org before you create a scratch org.

For this, you need to login to Dev/Sandbox Org from CLI

Run the force:auth:web:login CLI command on a directory where code for deploy to sfdx will be available.

sfdx force:auth:web:login –d

or

sfdx force:auth:web:login --setdefaultdevhubusername --setalias {ALIAS HERE}

NOTE: Login must be a valid login to your Dev/Sandbox Org and with Admin permissions.

3.     Configure your local project

The project configuration file sfdx-project.json indicates that the directory is a Salesforce DX setup project. The configuration file contains project information and facilitates the authentication of scratch orgs and the creation of second-generation packages. It also tells the Salesforce CLI where to put files when syncing between the project and scratch org.

4.     Configure your local project

After you create the scratch org definition file, you can easily spin up a scratch org and open it directly from the command line.

a)      Create the scratch org

  • Create a scratch org for development using a scratch org definition file. The scratch org definition defines the org edition, features, org preferences, and some other options.
  • Specify scratch org definition values on the command line using key=value pairs
  • Create a scratch org with an alias
  • Create a scratch org for user acceptance testing or to test installations of packages
  • Indicate that this scratch org is the default
  • Specify the scratch org’s duration, which indicates when the scratch org expires (in days)

b)      Open the org

  • To open the scratch org: sfdx force:org:open -u <username/alias>
  • To open the scratch org in Lightning Experience or open a Visualforce page, use the –path parameter: sfdx force:org:open –path lightning

c)       Set default user

Copy the username and enter the following command to set the defaultusername:

sfdx force:config:set defaultusername={SET THIS TO NEW SCRATCH ORG’S USERNAME FROM THE ABOVE  COMMAND}

d)      Display All Orgs

Run the following command to confirm the default Dev Hub [marked with (D)] and Active Scratch Org [marked with (U)]:

sfdx force:org:list --all

5.        Push the source from your project to the scratch org

To push changed source to your default scratch org:

sfdx force:source:push

To push changed source to a scratch org that’s not the default, you can indicate it by its username or alias:

sfdx force:source:push --targetusername [email protected]
sfdx force:source:push -u [email protected]
sfdx force:source:push -u MyGroovyScratchOrg

Selecting Files to Ignore During Push. It’s likely that you have some files that you don’t want to sync between the project and scratch org. You can have the push command ignore the files you indicate in .forceignore.

If Push Detects Warnings. If conflicts have been detected and you want to override them, here’s how you use the power of the force (overwrite) to push the source to a scratch org.

sfdx force:source:push –forceoverwrite

6. Salesforce DX Setup – Develop the app

a.       Create Source Files from the CLI

To add source files from the Salesforce CLI, make sure that you are working in an appropriate directory.

Execute one of these commands.

apex:class:create
apex:trigger:create
lightning:app:create
lightning:component:create
lightning:event:create
lightning:interface:create
lightning:test:create
visualforce:component:create
visualforce:page:create

b.       Edit Source Files

To edit a FlexiPage in your default browser—for example, to edit the Property_Record_Page source—execute this command.

sfdx force:source:open -f Property_Record_Page.flexipage-meta.xml

7.     Pull the source to keep your project and scratch org in sync

After you do an initial push, Salesforce DX tracks the changes between your local file system and your scratch org. If you change your scratch org, you usually want to pull those changes to your local project to keep both in sync.

During development, you change files locally in your file system and change the scratch org using the builders and editors that Salesforce supplies. Usually, these changes don’t cause a conflict and involve unique files.

By default, only changed source is synced back to your project.

To pull changed source from the scratch org to the project:

sfdx force:source:pull

To pull source to the project if a conflict has been detected (read more):

sfdx force:source:pull –forceoverwrite

8.     Salesforce DX Setup – Run tests

When you’re ready to test changes to your Salesforce app source code, you can run Apex tests from the Salesforce DX CLI. Apex tests are run in your scratch org.

You can also execute the CLI command for running Apex tests (force:apex:test:run) from within third-party continuous integration tools, such as Jenkins.

9.     Export The Package.xml

Export package.xml file into the temporary directory. Type the commands below in the root folder of your Salesforce DX project:

sfdx force:mdapi:retrieve -r ./temp -u {TARGETUSERNAME} -k  {SFDC PROJECT SOURCE LOCATION}\src\package.xml

10.       Convert Source code to Salesforce  DX

Convert the source code to the Salesforce Developer Experience project structure by running the following command:

sfdx force:mdapi:convert --rootdir temp --outputdir force-app

11.        Track Changes Between the Project and Scratch Org

To view the status of local or remote files:

sfdx force:source:status 

12. Salesforce DX Setup – Sync up

Sync the local version with the version deployed to Scratch Org for every change and test the changes on the Scratch Org by repeating the above steps. Once the testing is completed, we need to convert the source from Salesforce DX format to the Metadata API format. This is done by running the following command:

sfdx force:source:convert --outputdir {OUTPUT DIRECTORY HERE}

Copy the modified metadata files from this output location to the actual source location where the metadata files are downloaded from Dev/Sandbox Org to deploy the files to the server.

[Salesforce / Back To Basics] How to make a field required based on selected picklist value

For this new Back To Basics post, welcome Akashdeep Arora, Salesforce Evangelist/Consultant at HyTechPro. He started Salesforce journey in 2015. 3X Salesforce Certified Professional, 4X Trailhead Ranger, 5X Trailhead Academy Certified.Founder of #BeASalesforceChamp campaign.


Well, Astro turned 5 recently. So, what’s better than writing something related to Astro. As we all know, when you need a guide, Astro’s there for you.

#Astroturns5 #AppyBirthday #BeASalesforceChamp

Albeit, it sounds easy but still many Developers/Admins gets stuck when they want to make a field required based on one value selected from picklist field. Now, you must be thinking the way to achieve it.

We have different ways to make a field required:

  • Required Checkbox while field creation
  • Page Layout
  • Validation Rule
  • Using custom code (Visualforce Page, Lightning component, Apex Trigger to say a few)

But our scenario is little bit different as we want to make it required based on criteria, i.e. selected picklist value must be Astro.

Yay, let’s begin the fun without any delay.

The easiest way to achieve it is to use a validation rule. We have two fields:

  • Salesforce Character (a picklist field with values Appy, Astro, Codey, Cloudy and Einstein)
  • Astro Mom (a text field).

Here, we go.

After saving the rule, it will look like below:

Well, it’s time for testing. Testing is very necessary for anything. (Wink)

Let’s create a record without giving value in the Astro Mom text field and Select “Astro” from Salesforce Character picklist field like below:

As soon as you click on the Save button, it will give you an error “Please enter Astro Mom“.

Wohoooo, our validation rule is perfect it seems. Now, let’s provide the name of Astro Mom in the text field and click on Save button.

Hurrayyy, the record is saved this time. This is how you can make any field required based on selection of a picklist field value.

Don’t compare yourself with others.

You are best.

#Beasalesforcechamp

[Salesforce / LWC] Autocomplete magic with HTML Datalist

Ivano Guerini is a Salesforce Senior Developer at Webresults (Engineering Group) since 2015.
He started my career on Salesforce during his university studies and based his final thesis on it.
He’s passionate about technology and development, in his spare time he enjoys developing applications mainly on Node.js.


The <datalist> element is a new tag available in the HTML5.
This element can be used to create native autocomplete dropdowns without using complex JS and DOM manipulation for data filtering.

As you may have experienced, autocomplete picklist is a usefull component commonly used in forms to facilitate users in finding the correct value in case of very large lists of values.

In this article post, you’re going to learn how to use the datalist element to create a autocomplete dropdowns as Lightning Web Component.

For the TL;DR guys over there, this is the repo.

Let’s get started.

First let’s see how it works in an HTML page.

Simply write this code in an HTML page and we obtain a autocomplete dropdown like the below.

<input list="countries">

<datalist id="countries">
	<option>Italy</option>
	<option>Spain</option>
	<option>France</option>
	<option>USA</option>
	<option>England</option>
	<option>Belgium</option>
	<option>Brazil</option>
	<option>Mauritius</option>
	<option>Colombia</option>
	<option>Portugal</option>
	<option>Russia</option>
	<option>Mauritania</option>
</datalist>

Simple like that, all without any JS code.

Now let’s try to do the same in Salesforce.
Open your favorite IDE, and create a new LWC component, naming it ‘autocomplete’.

The html template we report the same code written above.

<template>
    <input id="input" name="input" list="countries" class="slds-input" type="text" />
    <datalist id="countries">
		<option>Italy</option>
		<option>Spain</option>
		<option>France</option>
		<option>USA</option>
		<option>England</option>
		<option>Belgium</option>
		<option>Brazil</option>
		<option>Mauritius</option>
		<option>Colombia</option>
		<option>Portugal</option>
		<option>Russia</option>
		<option>Mauritania</option>
	</datalist>
</template>

If we try to execute this component, we will see that it does not work as we would expect.
This is because the link between the input and the datalit is managed through the Id attribute. But as Salesforce reminds us:

The IDs that you define in HTML templates may be transformed into globally unique values when the template is rendered. If you use an ID selector in JavaScript, it won’t match the transformed ID.

To overcome this problem we can take advantage of a few lines of JS code, hooking up to the rerenderCallback.
Then in the Javascript controller we write the following function:

renderedCallback() {
     let listId = this.template.querySelector('datalist').id;
     this.template.querySelector("input").setAttribute("list", listId);
}

This code simply searches for our Datalist element and retrieves the ID generated by Salesforce, and consequently updates the input list attribute with the new Value.

Again the rendered callback can run a lot of times, but our code must be executed only once. To do it we can use a private attribute to know if the renderedCallback has been already executed:

initialized = false;

renderedCallback() {
        if (this.initialized) {
            return;
        }
        this.initialized = true;
        let listId = this.template.querySelector('datalist').id;
        this.template.querySelector("input").setAttribute("list", listId);
    }

Now our LWC component will work as autocomplete dropdown.

Let’s evolve it a bit, using dinamic options and decorating it with a label ad other attributes.

The HTML template will tranform like this:

<template>
    <label class="slds-form-element__label" for="input">
        <template if:true={required}>
            <abbr class="slds-required" title="required">* </abbr>
        </template>
        {label}
    </label>
    <div class="slds-form-element__control">
        <input id="input" name="input" list="valueList" placeholder={placeholder} required={required} class="slds-input" type="text"  />
        <datalist id="valueList" class="">
            <template for:each={values} for:item='item'>
                <option key={item.key} value={item.value}>{item.value}</option>
            </template>
        </datalist>
    </div>
</template>

In the JS controller we handle this values with @api decorator.

import { LightningElement, api } from 'lwc';

export default class Autocomplete extends LightningElement {
    @api values;
    @api label = '';
    @api name = '';
    @api required;
    @api placeholder = '';
    initialized = false;

    renderedCallback() {
        if (this.initialized) {
            return;
        }
        this.initialized = true;
        let listId = this.template.querySelector('datalist').id;
        this.template.querySelector("input").setAttribute("list", listId);
    }

}

Full repo here.

Introducing Dadela, a brand new business-oriented programming language

 
Today’s post has been written by Nikos Mitrakis, the creator of Forceea, an amazing Data Factory Framework for Salesforce.

Some facts about Nikos:

  • Salesforce Developer at Johnson & Johnson EMEA Development Centre (EDC)
  • Started his Salesforce journey in 2014
  • Has passed 10 certifications, including Certified Application Architect
  • Holds a Physics degree
  • Leader of Limerick, Ireland Developer Group
  • Married since 1994, has a daughter
  • Loves watching sci-fi movies and good comedies
  • Lives in Limerick, Ireland

Introduction

Dadela (pronounced dadèla) is a new programming language, designed with the intention to improve the way we generate data.

Dedala is business-oriented (not object-oriented) and it can be used by a user without programming skills (e.g. a tester or a business analyst).

The language specification is a project initiative on GitHub.

It was originally designed for Forceea data factory framework.

In Dadela we use the following language elements

  • The Environment is the system (programming language or application) that hosts Dadela’s components and capabilities, sets the execution limitations and defines the integration details for sources and destinations
  • A component is a language element. There are various components: attributes, variables, lists, entity definitions, templates and operations
  • A repository is a physical (e.g. a file) or a virtual (e.g. a database record) storage for the components
  • A library is a special repository, containing templates and lists
  • A template is a blueprint for creating records of an entity
  • An entity is a database table or a matrix. It can be a Salesforce SObject, an Oracle table, an Excel worksheet, etc
  • An operation is a process that creates/inserts records or exports records in text format (JSON) or CSV)
  • A source is a one-way integration between an external database and the Environment for retrieving records
  • A destination has the opposite direction (from the Environment to an external entity for inserting/exporting records

Lists play a key role in Dadela. A list is something like (item1,  item2,  item3), using a comma to separate the list items. In fact, all repository components can be considered as list items. Some examples:

number x: 100, # a numerical variable
list myList: (100, 200, 300), # a list
template BigAccounts: ( ... ), # a template
entity Account: ( ... ), # an entity definition

Lists may contain other lists or variablesVariables are referenced using @ and lists with !

number myVar1: 100,
number myVar2: 1 + myVar1, # myVar2 = 101
list myList1: (one, two, three),
string five: five, # @five = "five"
list myList2: (!myList1, four, @five), # myList2 = {one, two, three, four, five}

Of course, comments are inserted with #.

We don’t have the space to go deeper, but you’ve got the idea: the main usage of variables is to assign the same value to different components, facilitating the construction of entity definitions.

Create a template

The best way to understand a new language is “by example”. So, let’s suppose I am a business user trying to create and insert records for Opportunities, in order to prepare data for User Acceptance Testing (UAT). In my Environment I’ll create a new repository (a library), with the name “SalesTemplates” and a template in the library for the “Opportunity” entity.

Repository: SalesTemplates

template BigOpportunities: (
    Name: copy field(AccountId) from(Description),
    Name: static value(" - "),
    Name: serial type(number) from(1) step(1) scale(0) format(000),
    Amount: random type(number) from(1M) to(10M) scale(-3),
StageName: random type(picklist) except(Closed Won, Closed Lost)
)

 Let’s “translate” the above, line by line:  

template BigOpportunities: (
  • start the definition of a template called “BigOpportunities”  and execute the following steps for each generated record
Name: copy field(AccountId) from(Name),
  • for the values of the Opportunity field “Name” find the Account record which is related to the lookup Opportunity field “AccountId” (the AccountId field stores the ID of a related Account record)get the value of the (Account) field “Description” from this record  
Name: static value(" - "), 
  • for the values of the Opportunity field “Name”add the string ” – ” after the previous value
 Name: serial type(number) from(1) step(1) scale(0) format(000), 
  • for the values of the Opportunity field “Name”get serial numbers starting from 1, adding 1, with rounding to 0 decimal pointsformat the result like 001, 002, 003, …add the result after the previous value
 Amount: random type(number) from(1M) to(10M) scale(-3),
  • for the values of the Opportunity field “Amount” get random numbers, with minimum number 1,000,000, with maximum number 10,000,000, with rounding to 1,000 
StageName: random type(picklist) except(Closed Won, losed Lost),
  • for the values of the Opportunity field “StageName” get any value from the picklist values of this field, except from “Closed Won” and “Closed Lost”
)
  • ends the field definitions of this template

Field definitions

Dadela has many field definitions, in 4 types (commands)

copy

  • These definitions copy the value of another field or the value of a field from a related (lookup) record

static

  • Static definitions just display a string, number, date/datetime or boolean value

serial

The serial definitions create serial values for

  • numbers, dates, datetimes and lists

random 

The random definitions create random values for

  • numbers, booleans and strings, dates and datetimes, lists and picklists, lookup fields, emails, phone numbers, URLs, addresses (street, postal code, city, province, country), first and last names, and text sentences

Create the entity definition

Now, let’s continue our example. In our Environment, we create a new repository, with the name “MyEntities”.

Repository: MyEntities

language: French, 
locality: France (North Europe, Europe, EU),  

entity Account: (
    records: 100,
alias: BigAccounts,

    Rating: random type(picklist) except(Hot),
    Phone: random type(phone) format("(30) 210 dD-00-DD"),
    Industry: random type(picklist),
    Type: random type(list) value(Prospect, Customer - Direct, Customer - Channel), 
  
    # addresses
    ShippingStreet: random type(street) group(shipping),
    ShippingPostalCode: random type(postalcode) group(shipping),
    ShippingCity: random type(city) group(shipping),
    ShippingState: random type(state) group(shipping),
    ShippingCountry: random type(country) group(shipping)
),

entity Opportunity: (
    template: SalesTemplates.BigOpportunities,
records: 200,
alias: MyBigOpportunities,
virtual MyField: random type(list) value(Closed Won, Closed Lost),
    StageName: copy from(MyField)
)

 Let’s “translate” again: 

language: French,
  • the default language of names (first/last) and addresses in this repository will be “French” 
locality: France (North Europe, Europe, EU),
  • the default geographic area (locality) in this repository will be “France”, which will be a member of other localities (“North Europe”, “Europe” and “EU”) 
entity Account: ( ... ),
  • set the field definitions for accounts with the default number of records to be 100 with random values for the fields Rating, Phone, Industry and Type with random “real” addresses from France, in French
entity Opportunity: ( template: SalesTemplates.BigOpportunities,
  • use the field definitions from template “BigOpportunities” in repository “SalesTemplates”
virtual MyField: random type(list) value(Closed Won, Closed Lost),
  • define a “virtual” field: a virtual field is like a variable
StageName: copy from(MyField)
  • get the value of the virtual field (we used this for demonstration purposes – in a real situation, we use more than one virtual fields to construct a field definition)

Note that the definition for the field “Amount” will be the same as the definition in the template (this is the purpose of a template, after all).Of course, we could have defined a list for the stages inside the entity definition, or it could be a list in the repository or in a library, e.g.

entity Opportunity: (
list stages: (Closed Won, Closed Lost),
    ...
    StageName: random type(list) value(!stages)
)

Operations

The next step is to generate and store our data.

insert

If we want to insert the records into a “database”:

  • We configure a destination on our Environment. This destination could be a Salesforce org, or a SQL Server database.We use an insert operation:
insert MyBigOpportunities: (
destination(MySalesforceOrg1) group(MyGroupA)
),

The (optional) group parameter assigns a “tag” to the inserted records. This grouping is very helpful when we use the inserted records for further processing.

create

Another solution could be the create operation:

create MyBigOpportunities: (group(MyGroupA)),

Now we just generate the opportunity records and we can insert or export them later.

export

And finally, for exporting to JSON or CSV:

export MyBigOpportunities: (
destination(Ora1)
type(json) group(MyGroupA)
),

No magic here! The Environment will export our opportunities in JSON format.

Conclusion

We had a very short introduction to the syntax and capabilities of Dadela. If you are interested to learn more, you can find all the details on the GitHub project.

Closing this article, I’d like to remind that the language specifications are open for discussion and contribution to the further development and application of the language.

Powered by WordPress & Theme by Anders Norén