Friday, December 30, 2016

ISV App Strategy

App Type

  1. ISVforce App
    • app that extend Sales or Service Cloud
    • can be sell only to existing Salesforce customer.
    • if we use some Salesforce licence dependencies feature, need to make sure the user also have licence from Salesforce.
    • our customer have to purchase the license from Salesforce
    • Licence type mostly Sales and Service cloud
  2. Embedded app (OEM Embedded app)
    • app that does not rely on Sales cloud or Service cloud functionality.
    • can be sell to existing customer or customer who does not use Salesforce at all.
    • have access to App Cloud platform.Although they have access to certain Sales and Service cloud object such Leads,Opportunities they can't surface those to customer.
    • by contract,Salesforce does not give permission to rebuild Sales or Service Cloud functionality within OEM Embedded app.
    • the licence is embedded in application for new customer and existing customer but existing customer can choose to assign their ISV app licence rather than using embedded user licence.
    • Licence type,Customer Community (optional) and Customer Community Plus(optional)
Both ISV application licences provided by partner.

Why would you want to build an ISVforce app instead of an OEM Embedded app?
The app displays data in Opportunity and Lead objects.

Why would you want to build an OEM Embedded app instead of an ISVforce app?
Your target customers may not already have Salesforce.

What kind of Salesforce licenses must be included in a OEM Embedded app?

In your special partner DE org, you’ve created an app that you are ready to distribute. Displaying data from which object in your solution would prevent you from being able to use the OEM Embedded app type?
Case . We still can use Account and Contact in OEM Embedded app type.

Trailhead :Select an App Type

Thursday, December 29, 2016

Salesforce1 Mobile Basic : Creating Object-Specific Quick Actions

Five types of object-specific action:
  • Object-specific CREATE ACTION create records that are automatically associated with related records.
  • Object-specific UPDATE ACTION make it easy for users to edit records. You can define the fields that are available for update.
  • Object-specific LOG A CALL actions let users enter notes about calls, meetings, or other interactions that are related to a specific record.
  • Object-specific CUSTOM ACTIONS invoke Lightning components, Visualforce pages, or canvas apps that let users interact with or create records that have a relationship to an object record.The Visualforce page for an object-specific custom action must include the standard controller for the relevant object.
  • SEND EMAIL ACTION, available only on CASES, give users access to a simplified version of the Case Feed Email action on Salesforce1.

Wednesday, December 21, 2016

Entity is not api accessible when saving Apex class

Entity is not api accessible 

The error can be due to :

The object name is not stated correctly ,it happens when we use custom object we forgot to include __c :

Example : Use incorrectly MyObject instead of MyObject__c

Or some typo,I am not sure why it didnot give proper error but some of the typo below my cause some issue .Note service  is not declared in the code below.

Opportunity_Service  service1 = new Opportunity_Service();
List<Opportunity_Service.Result> results = opportunities);

Friday, December 09, 2016

System.UnsupportedOperationException: ConnectApi methods are not supported...

I am using ConnectorAPIHelper to post Chatter notification from apex code.When I run my apex test class it giving this exception :
System.UnsupportedOperationException: ConnectApi methods are not supported in data siloed tests. Please use @IsTest(SeeAllData=true).

It seems in order to cover the class that use ChatterApi, the test class need to be SeeAllData=true .

In my case, because I only have one line method that call ChatterApi , I think it's better use Test.isRunningTest instead of SeeAllData=true.

 public static void postChatter(){
     //exclude this from testing because in order to test ChatterApi ,we must set SeeAllData=true.
     //This class is test separately so it can be ignore for this testing.
          //send chatter notification
          ConnectApi.FeedItem fi = (ConnectApi.FeedItem)ConnectApiHelper.postFeedItemWithMentions(Network.getNetworkId(), 'me', 'Hi ,'+recipientChatter+ '-There has been an in Batch Job.Please check');

More info please refer here .

Thursday, December 08, 2016

System.AsyncException: trigger must be associated with a job detail

System.AsyncException: trigger must be associated with a job detail
I am writing test class for schedule and bump into this exception.The reason is , make sure no space at jobName. The class can be call by :

System.schedule(jobName, cronExpression, schedulableClass) ;

Notice this will throw the exception . 'Opp_Update_Schedule 5.00 '

      // Schedule the test job
      String jobId = System.schedule('Opp_Update_Schedule 5.00 ',
                        new Opportunity_Update_Schedule(100));

This will not throw exception :'Opp_Update_Schedule'. Remove space, I haven't test with special character (you might want to test) but I remove it anyway and it run.
      // Schedule the test job
      String jobId = System.schedule('Opp_Update_Schedule',
                        new Opportunity_Update_Schedule(100));
Have a nice day.

Tuesday, November 22, 2016

User is already a Member of this group.

When we deactivate the user who is member of Chatter group, the user will be invisible from the Chatter Group.We not able to find the user using this query :
SELECT Id, CollaborationGroupId, MemberId FROM CollaborationGroupMember WHERE CollaborationGroupId =: groupId

Also the user is not inside Chatter Group --Members .

But when we activate the user, automatically it will be appear in Chatter Group.

All of this is handled by Salesforce.

Please note this when we plan to add user into the Group automatically because we may bump into exception below : 

User is already a Member of this group. 

So we need to verify if the user is a member of the group before adding it.

Friday, November 18, 2016

Finding Distinct in Report using Formula

I never thought this can be done using formula, but yes.Please refer to here.

Scenario : We want to see total how many Account that has Opportunities.

Create one formula field in Account object with return type Number and 0 Decimal place.Place 1 at Formula field.

Example of the report below, we want to know how many Account that has Opportunity.

So we click Customize Report, Click on Unique Account -> Choose Summarize this Report ,select Sum and Apply.

Total of Account is 8.

Tuesday, November 08, 2016

Processes Can Execute Actions on More Than One Criteria but...

Previously before Summer '16 we are not able to evaluate the next criteria if first criteria is correct.So once the process fall into true condition , implement the action and that's it.It will stop.

In Summer'16 :Processes Can Execute Actions on More Than One Criteria , we able to evaluate next criteria once the process builder process the conditon for current criteria.(ugh ...not sure I am explaining well). It is something like this :

Previously it works something like this.Notice that if condition1 is fulfilled , it will never go to else condition.


else if(condition2==true){

Now , we can proceed with next criteria can be like this :


In order for it to evaluate the next criteria, just click on the STOP and it will give the screen shot like below.REMEMBER ,THIS FEATURE DOES NOT WORK FOR SCHEDULE ACTIONS.

Tuesday, October 18, 2016

Process Builder not working during record insertion and fail to launch Flow

I created Process Builder to automatically add user into Chatter group , refer to here.It works fine when I update the user but it fail when I create new user.

An error occurred at element Add_User_to_All_Chatter_Group (FlowRecordCreate).
INSERT --- INSERT FAILED --- ERRORS : (MIXED_DML_OPERATION) DML operation on setup object is not permitted after you have updated a non-setup object (or vice versa): CollaborationGroupMember, original object: User

I am assuming during creation, the user id is not yet committed, so it not able to set variable in Flow.After do some googling , I found some solution that can be applied on my case.

I also add new Record Lookup in my Flow, to check if the user already exist in Chatter group and Decision when the Lookup Result is not found.

Good thing, due to this I can remove custom field that I used to indicate if the User already added into the group.

In Process Builder , I use Scheduled Actions so I have to use  'Formula evaluates to true'.Scheduled Actions option is not available if 'Conditions are met' is ticked.In order to run this process builder as soon as possible,I choose 1 Hours Before LastModified.

After that, I create new user and there no more error.Also working fine for update.

Have a nice day.

Tuesday, September 20, 2016

Automatically adding user into Chatter group using Process Builder

I am looking for solution to automatically add user to Chatter group and found this interesting solution using Flow Trigger and Workflow rule.However I am not able to implement it because Flow Trigger is pilot feature not GA feature.If I really want it, I can just call Salesforce Support to enable it but I m kinda of lazy.

But I just tweak this solution by using Process Builder.I think the solution is available out there but let me just update mine.

Please vote for this idea : Automatically add individuals to Chatter Group upon provisioning new user

If you are enabling namespace you might face this issue : Workflow Action Failed to Trigger Flow when triggering Flow created after enabling a namespace , and this solution might not work for you.

Step 1 : Create a Chatter Group
Step 2: Create custom field datatype checkbox in User object.
This is depending on how you want to implement logic to add user.In my case, if this               checkbox is false it will add user to the group.My custom field name is 'Sales Info Center Group'.

Step 3 : Create Flow
  • Create a variable to receive user id parameter.

  • Drag a Record Create to the Canvas
    • At the Assignment > Create > Standard>CollaborationGroupMember
    • At field choose Standard > CollaborationGroupId > and also add another field MemberId which is referring to the variable UserId that you created just now.The click OK.
  • Set Element as Start Element by clicking the green icon on Record Create 

  • Save your flow and activate it.

Step 4:Create Process Builder

  • Choose User object, for my case I start the process when a record is created or edited.
  • Add criteria like below .My condition is if user is Active and Sales Info Center Group is true.Save

  • I add two action , first it will call the Flow that we created previously.Second, it will update checkbox field to true like picture below.Don't forget to save your Process Builder and activate it.
Step 5: Testing

Choose one active user, update the record.Check out the group member.

Share with me if you have any idea or comment.Thanks.

Friday, August 19, 2016

Visualforce error : Maximum view state size limit (135KB) exceeded. Actual view state size for this page was 136.031KB

I created a visualforce page to display report that join between Attachment and Content version based on Attachment Parent Type.I bumped into view state exception when retrieving attachment on Opportunity that contains more than 1000 row.

Note that listAttachment and listMigrationObject is the biggest contributor on this exception.

Below I share snippet on how I retrieve listAttachment that causing exceed ViewState.

   listAttachment = [Select Name,Id,ParentId,Parent.Type,Owner.Name,Owner.Id ,Owner.IsActive ,ContentType,isPrivate from Attachment where Parent.Type =:selectedParent ];
  Map<Id,Attachment> mapAttachment = new Map<Id,Attachment>();
  for(Attachment att : listAttachment){

I change the code to below :

for(Attachment att : [Select Name,Id,ParentId,Parent.Type,Owner.Name,Owner.Id ,Owner.IsActive ,ContentType,isPrivate from Attachment where Parent.Type =:selectedParent ]){

Note that assigning SOQL to list and directly use SOQL in the loop will make a different.

See, there is no longer exception. I will do the same on the other list.

You might want to check on An Introduction to Visualforce View State .

Have a great weekend.

Thursday, August 04, 2016

Style like Homepage in Salesforce

The requirement is to create visualforce and make it as one of Homepage component.The style should be same as Homepage style.

It works until a user comes to me and said;

"I notice the blue section in the component is different from Homepage component."

Krik... Krikk.. I didn't notice that until I have to print screen and put it side to side.Oh,actually it is different, I thought it just screen reflection.So how can I get the Homepage style color.

This is my page definition,note I use tabStyle = Account .So it gives me the blue color same like Account tab.

<apex:page controller="MyController" readOnly="true" showHeader="false" standardStylesheets="true" sidebar="false" applyHtmlTag="false" applyBodyTag="false" docType="html-5.0">    
<apex:pageBlock title="My Account" tabstyle="Account">

By default if we are not defining the tabStyle,it will use Homepage style ...but in my case it gives me black color.

In order to get the Homepage style I need to set showHeader="true"  , by default showHeader is true except for Salesforce1 and Lightning Experience.Remember to remove applyHtmlTag when we set showHeader="true".

The modified code is

<apex:page controller="MyController" readOnly="true" showHeader="true" standardStylesheets="true" sidebar="false"  docType="html-5.0">  
<apex:pageBlock title="My Account" >
Now it gives me the same blue.

Have a nice day.

Friday, July 29, 2016

Data Management : Importing and Exporting Data

Note: All credit goes to Salesforce, I am just a developer who enjoy playing trailhead and try to make note to myself.

Importing Data

Two methods of importing data : 
When to use Data Import wizard :

  1. Need to load less than 50000 records
  2. The objects that need to be imported is supported by wizard
  3. No need automation process
When to use Data Loader :
  1. Need to load 50000 to 5 Million records.
  2. The object is not supported by Data Import Wizard
  3. Want to schedule regular data loads

Data Import
Useful tips for cleaning data using Excel

Salesforce Trailhead link : Importing Data

Exporting Data

Two methods of exporting data
  1. Data export wizard - accessible through the Setup menu. It allows you to export data manually once every six days (for weekly export) or 28 days (for monthly export). You can also export data automatically, at weekly or monthly intervals.
  2. Data Loader -this is a client application that you must install separately. It can be operated either through the user interface or the command line. The latter option is useful if you want to automate the export process, or use APIs to integrate with another system.
Salesforce Trailhead link : Exporting  Data

Data Modelling :Creating object relationship

Note: All credit goes to Salesforce, I am just a developer who enjoy playing trailhead and try to make note to myself.

Types of Object Relationship

  1. Lookup
    • relationship that links one object to another object.
    • can be used to create 1:1 or 1:M relationship
  2. Master Detail
    • parent:child relationship.
    • master record controls certain behavior of the details or subdetail record.
    • ownership and sharing is determined by master record.
    • when master record is deleted,the detail also will be deleted along with it.
    • master detail relationship always required on detail record.
    • use for tight binding between two objects
    • master object can also contain rollup summary field.

Differences between Lookup and Master detail relationships

  1. Master detail relationship
    • cannot create detail without master
    • detail is also deleted when master is deleted
    • the sharing rules is inherited from the master record
    • number of master detail relationships are limited based on platform edition and licence
    • can't set profile object permission for a detail record.The details record inherits permissions from the master record
    • master-detail relationship are automatically included in  report record types
  2. Lookup relationship
    • to reference commonly shared data, such as reference data
    • to relate multiple parent records to the child record
    • to link two objects together when you don't want the behavior of the master-detail relationships such as sharing rules,profile permission and cascade delete.
    • if the details object has its own tab, then look up is the choice. 

Source:Creating object relationship

Saturday, July 23, 2016

Apex Basics & Database : Writing SOSL Queries

Note: All credit goes to Salesforce, I am just a developer who enjoy playing trailhead and try to make note to myself.
What is SOSL?
Salesforce Object Search Language (SOSL) is a Salesforce search language that is used to perform text searches in records. Use SOSL to search fields across multiple standard and custom object records in Salesforce. SOSL is similar to Apache Lucene.

Differences and Similarities Between SOQL and SOSL
Like SOQL, SOSL allows you to search your organization’s records for specific information. Unlike SOQL, which can only query one standard or custom object at a time, a single SOSL query can search all objects.
They are same in : 
  • allows you to search your organization’s records for specific information
They are not same:
  • SOQL can only query one standard or custom object at a time, a single SOSL query can search all objects.
  • SOSL matches fields based on a word match while SOQL performs an exact match by default (when not using wildcards).For example, searching for 'Cloudy' in SOSL returns records whose field values are 'Cloudy' or 'Cloudy Day', but SOQL returns only records with field values of 'Cloudy'.
  • SOQL and SOSL are two separate languages with different syntax.
    • Use SOQL to retrieve records for a single object.
    • Use SOSL to search fields across multiple objects. SOSL queries can search most text fields on an object.

Basic SOSL Syntax

FIND 'SearchQuery' [IN SearchGroup] [RETURNING ObjectsAndFields]
  1. SearchQuery : is the text to search for (a single word or a phrase). Search terms can be grouped with logical operators (AND, OR) and parentheses. Can include wildcard characters (*, ?). The * wildcard matches zero or more characters at the middle or end of the search term. The ? wildcard matches only one character at the middle or end of the search term.Text searches are case-insensitive. For example, searching for Customer, customer, or CUSTOMER all return the same results.
  2. SearchGroup(optional): It is the scope of the fields to search. If not specified, the default search scope is all fields. SearchGroup can take one of the following values.
  3. ObjectsAndFields (optional):It is the information to return in the search result—a list of one or more sObjects and, within each sObject, list of one or more fields, with optional values to filter against. If not specified, the search results contain the IDs of all objects found.
List<List<sObject>> searchList = [FIND 'Wingo OR SFDC' IN ALL FIELDS 
                   RETURNING Account(Name),Contact(FirstName,LastName,Department)];
Account[] searchAccounts = (Account[])searchList[0];
Contact[] searchContacts = (Contact[])searchList[1];

System.debug('Found the following accounts.');
for (Account a : searchAccounts) {

System.debug('Found the following contacts.');
for (Contact c : searchContacts) {
    System.debug(c.LastName + ', ' + c.FirstName);

Single Words and Phrases 
A SearchQuery contains two types of text:

  1. Single Word— single word, such as test or hello. Words in the SearchQuery are delimited by spaces, punctuation, and changes from letters to digits (and vice-versa). Words are always case insensitive.
  2. Phrase— collection of words and spaces surrounded by double quotes such as "john smith". Multiple words can be combined together with logic and grouping operators to form a more complex query. SOQL and SOSL Reference 
Salesforce TrailHead

Thursday, July 21, 2016

Process Builder Exception : The record couldn’t be saved because it failed to trigger a flow

The record couldn’t be saved because it failed to trigger a flow. A flow trigger failed to execute the flow with version ID 3xxxxxxxxxxxxxx.  Contact your administrator for help.

The process builder is to update Country Contact with Account Country if the Contact Country is blank based on condition below :

When user uploads the Contact data without Account data it will throw an exception and I receive an email contains information below which is not so helpful.

An error occurred at element myDecision (FlowDecision).
The flow failed to access the value for myVariable_current.Account.Country__c because it hasn't been set or assigned.

Logically it should not run the process builder at the first place because the conditions are not fulfilled.I plan to raise ticket to Salesforce until I accidentally change the sequence of the conditions to :

Note I put AccountId condition before checking the Account Country__c.I run another test and wallahhh...the exception is gone.Contact is successfully inserted with Account details.I haven't see (yet) any documentation regarding on condition sequence in Process builder but it makes sense that we need to check the AccountId first before we check Account Country.

Hopefully this is helpful.Please let me know what your think.

Wednesday, July 20, 2016

Apex Basics & Database Writing SOQL Queries

Note: All credit goes to Salesforce, I am just a developer who enjoy playing trailhead and try to make note to myself.

Querying Related Records

Get child records related to parent record

Account[] acctsWithContacts = [SELECT Name, (SELECT FirstName,LastName FROM Contacts)
                               FROM Account 
                               WHERE Name = 'SFDC Computing'];
// Get child records
Contact[] cts = acctsWithContacts[0].Contacts;
System.debug('Name of first associated contact: ' 
             + cts[0].FirstName + ', ' + cts[0].LastName);

Querying Record in Batches By Using SOQL For Loops

With a SOQL for loop, you can include a SOQL query within a for loop. The results of a SOQL query can be iterated over within the loop. SOQL for loops use a different method for retrieving records—records are retrieved using efficient chunking with calls to the query and queryMore methods of the SOAP API. By using SOQL for loops, you can avoid hitting the heap size limit.

SOQL for loops iterate over all of the sObject records returned by a SOQL query. The syntax of a SOQL for loop is either:

for (variable : [soql_query]) {


for (variable_list : [soql_query]) {

It is preferable to use the sObject list format of the SOQL for loop as the loop executes once for each batch of 200 sObjects. Doing so enables you to work on batches of records and perform DML operations in batch, which helps avoid reaching governor limits.

insert new Account[]{new Account(Name = 'for loop 1'), 
                     new Account(Name = 'for loop 2'), 
                     new Account(Name = 'for loop 3')};

// The sObject list format executes the for loop once per returned batch
// of records
Integer i=0;
Integer j=0;
for (Account[] tmp : [SELECT Id FROM Account WHERE Name LIKE 'for loop _']) {
    j = tmp.size();
System.assertEquals(3, j); // The list should have contained the three accounts
                       // named 'yyy'
System.assertEquals(1, i); // Since a single batch can hold up to 200 records and,
                       // only three records should have been returned, the 
                       // loop should have executed only once

Challenge solution that I wrote

public class ContactSearch {
    public static List<Contact> searchForContacts(String lastName,String postalCode){
            List<Contact> lstContact=[Select Id,Name from Contact where LastName =:lastName and MailingPostalCode=:postalCode];
            return lstContact;
        catch(Exception e){
            return null;


 Salesforce trailhead

Monday, July 18, 2016

Apex Basics & Database : Manipulating Records with DML

Note: All credit goes to Salesforce, I am just a developer who enjoy playing trailhead and try to make note to myself.

Manipulating Records with DML

DML statements that are available:

  • insert
  • update
  • upsert-creates new records and updates sObject records within a single statement, using a specified field to determine the presence of existing objects, or the ID field if no field is specified.
  • delete
  • undelete
  • merge-merges up to three records of the same sObject type into one of the records, deleting the others, and re-parenting any related records.

Each DML statement accepts either a single sObject or a list (or array) of sObjects. Operating on a list of sObjects is a more efficient way for processing records.

Database Methods

Apex contains the built-in Database class, which provides methods that perform DML operations and mirror the DML statement counterparts.These Database methods are static and are called on the class name.

  • Database.insert()
  • Database.update()
  • Database.upsert()
  • Database.delete()
  • Database.undelete()
  • Database.merge()

Why it different with DML statement?

  • Database methods have an optional allOrNone parameter that allows to specify whether the operation should partially succeed. When this parameter is set to false, if errors occur on a partial set of records, the successful records will be committed and errors will be returned for the failed records. Also, no exceptions are thrown with the partial success option.
  • Database class contains methods that aren’t provided as DML statements. For example, methods used for transaction control and rollback, for emptying the Recycle Bin, and methods related to SOQL queries. 

Should You Use DML Statements or Database Methods?

Use DML statements 
If you want any error that occurs during bulk DML processing to be thrown as an Apex exception that immediately interrupts control flow (by using try. . .catch blocks). This behavior is similar to the way exceptions are handled in most database procedural languages.

Use Database class methods
If you want to allow partial success of a bulk DML operation—if a record fails, the remainder of the DML operation can still succeed. Your application can then inspect the rejected records and possibly retry the operation. When using this form, you can write code that never throws DML exception errors. Instead, your code can use the appropriate results array to judge success or failure. Note that Database methods also include a syntax that supports thrown exceptions, similar to DML statements.

About Transactions

DML operations execute within a transaction. All DML operations in a transaction either complete successfully, or if an error occurs in one operation, the entire transaction is rolled back and no data is committed to the database. The boundary of a transaction can be a trigger, a class method, an anonymous block of code, an Apex page, or a custom Web service method. For example, if a trigger or class creates two accounts and updates one contact, and the contact update fails because of a validation rule failure, the entire transaction rolls back and none of the accounts are persisted in Salesforce.

Code that I wrote for challenge:

public class AccountHandler {
    public static Account insertNewAccount(String accountName){
        Account newAccount =new Account(Name=accountName);
        insert newAccount;
            return newAccount;
        catch(DMLException e){
            return null;

Apex Basic and Database :Using SObject

Note: All credit goes to Salesforce, I am just a developer who enjoy playing trailhead and try to make note to myself.

Relationship between Sobjects and Salesforce record
Every record in Salesforce is natively represented as an sObject in Apex. For example, the Acme account record corresponds to an Account sObject in Apex. The fields of the Acme record that we can view and modify in the user interface can be read and modified directly on the sObject as well.Each Salesforce record is represented as an sObject before it is inserted into Salesforce. Likewise, when persisted records are retrieved from Salesforce, they’re stored in an sObject variable.

Some rules used for API names for custom objects and custom fields.

For custom objects and custom fields, the API name always ends with the __c suffix. For custom relationship fields, the API name ends with the __r suffix. For example:

  • A custom object with a label of Merchandise has an API name of Merchandise__c.
  • A custom field with a label of Description has an API name of Description__c.
  • A custom relationship field with a label of Items has an API name of Items__r.

Generic sObject datatype
If we don’t know the type of sObject that our method is handling, we  can use the generic sObject data type.We also can can cast Sobject to specific sObject type.Specify sObject type will allow us to  use dot notation.

But variables that are declared with the specific sObject data type can reference only the Salesforce records of the same type.

Generic sObjects can be created only through the newSObject() method. 
Also, the fields of a generic sObject can be accessed only through the put() and get() methods.
We can use dot notation in specific sObject type.


Apex Basic and Database : What is Apex ?

Note: All credit goes to Salesforce, I am just a developer who enjoy playing trailhead and try to make note to myself.

What is Apex?

programming language that uses Java-like syntax and acts like database stored procedures. Apex enables developers to add business logic to system events, such as button clicks, updates of related records, and Visualforce pages.


 Apex is:

  • Hosted—Apex is saved, compiled, and executed on the server—the platform.
  • Automatically upgradeable—Because compiled code is stored as metadata in the platform, Apex is automatically upgraded as part of Salesforce releases.
  • Object oriented—Apex supports classes, interfaces, and inheritance.
  • Strongly typed—Apex validates references to objects at compile time.
  • Multitenant aware—Governer limit.Because Apex runs in a multitenant platform, it guards closely against runaway code by enforcing limits, which prevent code from monopolizing shared resources.
  • Integrated with the database—It is straightforward to access and manipulate records. Apex provides direct access to records and their fields, and provides statements and query languages to manipulate those records.
  • Data focused—Apex provides transactional access to the database, allowing you to roll back operations.
  • Easy to use—Apex is based on familiar Java idioms.
  • Easy to test—Apex provides built-in support for unit test creation, execution, and code coverage. Salesforce ensures that all custom Apex code works as expected by executing all unit tests prior to any platform upgrades.
  • Versioned—Custom Apex code can be saved against different versions of the API.

Apex is similar in OOP in :
  • Classes, interfaces, properties, and collections (including arrays).
  • Object and array notation.
  • Expressions, variables, and constants.
  • Conditional statements (if-then-else) and control flow statements (for loops and while loops).
Additionally Apex supports:
  • Cloud development as Apex is stored, compiled, and executed in the cloud.
  • Triggers, which are similar to triggers in database systems.
  • Database statements that allow you to make direct database calls and query languages to query and search data.
  • Transactions and rollbacks.
  • The global access modifier, which is more permissive than the public modifier and allows access across namespaces and applications.
  • Versioning of custom code.
  • Apex is a case-insensitive language.

Sunday, July 17, 2016

Lightning Experience Development : User Interface Development Consideration

Note: All credit goes to Salesforce, I am just a developer who enjoy playing trailhead and try to make note to myself.

Two models of developing web app
Page Centric web application model
  • great to serve basic functionality.
  • not offer great user interactive experience
  • server side generate user interaction

App Centric mode
  • great user experience
  • client side
Three options that offered by Salesforce

Classic Visualforce

  • UI Generation - Server-side
  • Data and Business Logic-Apex standard or custom controller
  • Workflow
    1. User requests a page
    2. The server executes the page’s underlying code and sends the resulting HTML to the browser
    3. The browser displays the HTML
    4. When the user interacts with the page, return to step one.
  • Pros
    • Tried and true model
    • Easy to implement for greater productivity
    • Naturally splits large applications into small, manageable page
    • Has built-in metadata integration
  • Caveats
    • Limited interactivity (aside from added JavaScript functionality)
    • Higher latency, which degrades mobile performance
Visualforce as a JavaScript Application Container
-Empty visualforce with javascript code.In other word, Visualforce just add as javascript container.
  • UI Generation -Client-side (mostly JavaScript)
  • Data and Business Logic- Remote Objects or JavaScript Remoting
  • Workflow
    1. The user requests the “empty” Visualforce page containing only JavaScript includes
    2. The page is returned to the browser
    3. The browser loads the JavaScript application
    4. The JavaScript application generates the UI
    5. When a user interacts with the application, the JavaScript modifies the user interface as needed (return to the previous step).
  • Pros
    • Enables highly interactive and immersive user experiences
  • Caveats
    • Complex
    • No built-in metadata integration
    • Lack of an integrated developer experience. The Developer Console doesn’t explicitly support these JavaScript applications. Need to store javascript library in Static Resource
Lightning Components
  • UI Generation-Client-side (JavaScript)
  • Data and Business Logic-Apex controller
  • Workflow
    1. The user requests an application or a component
    2. The application or component bundle is returned to the client
    3. The browser loads the bundle
    4. The JavaScript application generates the UI
    5. When the user interacts with the page, the JavaScript application modifies the user interface as needed (return to previous step)
  • Pros
    • Enables highly interactive and immersive user experiences
    • Aligns with Salesforce user interface strategy
    • Built on metadata from the foundation, accelerating development
    • The Developer Console supports Lightning components, so there’s an integrated developer experience
  • Caveats
    • Higher learning curve compared to Visualforce
    • Higher complexity than Visualforce—you’re building an application, not a page
    • Since Lightning components are new, there are still some features that aren’t supported
    • There are a limited number of out-of-the-box components
Salesforce Trailhead Link

Lightning Experience

Note: All credit goes to Salesforce, I am just a developer who enjoy playing trailhead and try to make note to myself.
Which one I should use?Lightning Experience or Salesforce Classic?
Lightning Experience might be right for some or all of your org if:
  • Your sales team does business-to-business sales using accounts, contacts, leads, opportunities, custom objects, and the other sales features supported in the new user interface.
  • You want to pilot the new user interface with a group of sales reps.
  • You’re looking to reboot your Salesforce implementation. This is a great opportunity to introduce new features because you’re doing change management anyway.
Salesforce Classic might be right for you if:
  • Your sales team makes regular use of features that aren’t yet available in Lightning Experience, such as quotes, forecasting, or territory management.
  • You primarily use customer service tools or other non-sales features.
  • You want a single experience for your sales and service teams.
Some of features that might not work in Lightning Experience :
  • Custom Java script button.It can be replaced by point and click tools, Process builder, Visual Workflow and code driven approaches.
  • Some of Appexchange.Check out on the Lightning Ready certificate to ensure the apps is working on Lightning Experience.
  • Custom tab because tab is replaced by collapsible navigation menu at the left side.
  • Visualforce and apex.It works but it requires revision.

Setup User for Lightning Experince:
  • By default, the “Lightning Experience User” permission is automatically enabled for all users with a standard Salesforce profile.
  • If we have Standard User that should not get access to Lightning Experience move it to Custom Profile.
  • If we have Custom Profile user that should access to Lightning Experience, create Permission Set that includes 'Lightning Experience User'.
  • All above not applicable for Group Edition because Custom Profiles are not available .We can’t remove the “Lightning Experience User” permission from org’s standard profiles, and custom profiles aren’t available. So it’s “all or nothing” if we want to turn on Lightning Experience in Group Edition—all our users will be enabled to use the new interface. But we can control who is immediately switched into the new interface and who remains in the classic interface until they’re ready to switch themselves.
Trail Head Link Lightning Experience Basics

Thursday, January 21, 2016

Data Modelling :Creating custom object and fields

Note: All credit goes to Salesforce, I am just a developer who enjoy playing trailhead and try to make note to myself.

Best Practices for Custom Objects and Fields

  1. Unique naming: Make object and field names and labels concise, specific, and descriptive. And very importantly, unique. For example, if your recruiting app’s Position object has a field named Skill Set, use something like Candidate Skill Set on the Candidate object to describe applicants’ skills.
  2. Thoughtful architecture: When adding fields to an object, what’s the cleanest and most efficient way to capture data? For example, instead of a long list of checkboxes to track the regions that currently have a particular position open, use a picklist.
  3. Default field values: Don’t assign default values to fields that are both required and unique, as this can cause uniqueness errors.
  4. Careful renaming: If you’ve renamed objects or fields, check that these items reflect the new names:
    • List view names
    • Standard report names or descriptions that include the objects or fields
    • Email templates that contain the object or field names
    • Any other items you customized along with the renamed object or field — custom fields, page layout, or record types
    • Global data updates: Before changing a field type (for example from checkbox to picklist), make sure the change makes sense for all records that have that field.
  5. Help for users: Add help text when defining new objects or fields. Help text should describe exactly what the object or field is for.
Source:Creating custom object and fields

Data Modelling :Understanding Standard and Custom Object

Note: All credit goes to Salesforce, I am just a developer who enjoy playing trailhead and try to make note to myself.
In relational database such Oracle,MySql we use table to store data but in Salesforce we use object.Here the summary of term that use in relational database and the term that we use in Salesforce.

Relational Database Salesforce
Table Object
Column Field
Row Record

Standard Object - objects included by Salesforce by default such as Account,Opportunity,Leads.
Custom Object-object that created by user/developer to support the need of organization.

Fields and Relationships

Identitiy - ID
automatically assigned by 15 case sensitive characters.It is unique.

System Fields
Default read only field created by upon object created such as CreatedDate,CreatedBy,LastModifiedDate etc.

Name field
required but not unique, depend on how we want to identify the record.

Custom Fields
Created by user .Support type such as autonumber,picklist,text,geolocation etc.

Look up (link to other object) and Master Detail(parent child relationship)

Table is generated using Table Generator.
Source:Understanding Standard and Custom Object