Sunday, March 13, 2022

Logical Operators in Javascript (Part-I)

 

In this blog, we will learn about logical operators in JavaScript.

Trust me, it's going to be an amazing journey as logical operators in JavaScript are a little different 👿


We have 4 logical operators as below : 

  • OR ( || ) 
  • Null Coalescing ( ?? ) 
  • AND ( && ) 
  • NOT ( ! ) 

We will learn about the OR operator first.

  1. OR ( || )

In most languages OR is supposed to be used with Boolean values and give out only Boolean values ie return TRUE if any of the operands are TRUE else return FALSE ie 

    • TRUE || TRUE  -- > TRUE 
    • FALSE || TRUE --> TRUE 
    • TRUE || FALSE -- > TRUE 
    • FALSE || FALSE --> FALSE

But in JavaScript this operator works a little differently, we can not only use it Boolean operands but also with everything else as well ( any data type).

And No output will also not be necessarily Boolean rather can be any data type 🤯

OR operator works on the basis of truthy and falsy values (Refer to MDN docs if you need a refresher on truthy and falsy values)

Now let's look at the OR operator working. It evaluates all operands from left to right. If the left operand is truthy value. It will return it else it will return 2nd operand. 

If I try to put the above statement in other words, we already know that the OR operator returns TRUE unless both operands are FALSE ie 

If the first operand is a truthy value, it doesn't matter what the next operand is as output is going to be a truthy value or say first operand.

Only if the first operand is falsy value, now output will depend on 2nd operand. If it's truthy value it will lead to truthy value else a falsey value.

Let's look at some examples. 


We only discussed and saw examples, when we have only 2 operands but what If we have chain of operands. What happens in that case? 

Well, OR operator still acts the same and traverses from L-R searching for truthy values, and as soon as a truthy value is found it's returned else it keeps on moving towards the end of the chain and if no truthy value is found it returns the last value.

Let's look at an example


 

Note: While processing from L to R as soon as the first truthy value is returned and all the other operands are left untouched, this is called short-circuiting.

Let's take a look at another example to understand short-circuiting better.


If you notice in the above example fun1 and fun2 were never even executed because of short-circuiting.

Note: Remember in the JavaScript output of OR operator is not going to be necessarily Boolean rather will depend on which operand will get returned after evaluation and can lead to any data type


Thanks.

If you liked the post do support me by buying a pizza for me :D.

 

 

Thursday, March 10, 2022

Multiple objects in single DML ?

This is an extension of our earlier post where we read about how we can insert both parent and child in a single DML. If you haven't read it yet visit it by clicking.

Note: Usage of single DML to insert/update different object is not just limited to objects which are in a relationship rather it could be simply the creation of unrelated different objects on the occurrence of a certain event.

We already know the limit of the number of records that can be updated by a DML is 10,000 (Remember the Limit is for the whole transaction, not just one DML but in our case, our transaction consists of only one DML).

Now questions come to mind, can I also insert List<Sobject> that contains a mixture of Accounts and Contact records in total (2,400) records.

Before reading further try to think of the answer...

The default expectation is "Yes", having multiple Objects in the List should not impact the 10,000 limits and 2,400 is way below 10,000. But unfortunately, that is not the case.

If you try to insert 1,200 Accounts and 1,200 Contacts that are unrelated, below is a snippet of code used to add records.



You will receive the below error.

Error



But why this error?

When we know we can easily insert 10,000 records of Accounts or any other object for that matter when inserted/updated individually. (Code example below).


On deep diving into the issue we figured, when working with multiple objects, salesforce traverses through the list and creates chunks of records. 

Chunk is nothing but a subset of input array or list and each chunk contains records as per the below rules.

  • Each chunk will only contain records of one object type.
  • If object changes while traversing the list, the chunk also changes.
Assume you have a list of records as A1, A2, C1, C2, A3. 
They will be distributed as 
Chunk 1 --> A1, A2 
Chunk 2 --> C1, C2
Chunk 3 --> A3

  • In a chunk maximum of 200 records can come, the 201st record will be placed in the 2nd chunk.
  • In total for a successful DML, you can have a maximum of 10 chunks. 
  • Derivation from the above rule we can also say we can have at most 10 different types of objects in a Single DML which will lead to 10 different chunks
  • Data is committed chunk by chunk ie if for example, any trigger exists on records it will be called once for each chunk of records.

Taking the above example as a base,  when the Account trigger is called ( Trigger.new will only contain A1 and A2 first time then it will be called again (for chunk 3) and this time it will only contain A3.


Note: Chunking comes into the picture only if you are working with multiple objects, when doing data manipulation on a single object no chunking takes place.


Let's look at another example where DML could fail.

Example 1 :

Here we are adding different instances of multiple objects in a single list and inserting them.


But if you try to run above code it will fail although we are only inserting 11 records, it fails as it will lead to 11 chunks.


Just because every time an object changes, chunk also changes we can simply sort all the same type of object instances so they are part of a single chunk (200 max). 
We can resolve the above code by simply using sort() method which will sort the list putting all same types of instances in order and which will reduce chunk size to 5.(Code below) 


To resolve the earlier example of 1200 Accounts and 1200 Contacts we will have to distribute it in two DMLs as it can't be achieved via a single DML.



To summarize the topic, I will say there can be 3 scenarios if we are working with multiple Sobjects.

  • We have a hybrid list that contains different types of object records which are scattered like (Account1, Contact1, Lead1, Account2 ...). In this type of hybrid list, we can simply sort the list to reduce the chunk size.
  • We have two or three objects but their numbers are huge for example 1200 Accounts, 1200 Contact which will lead to 12 chunks, in this case, we will have to simply divide the records into multiple DMLs in case the number of chunks is above 10 otherwise we can use single DML.
  • If you are working with more than 10 types of objects, you will again end up with the same error as every time object changes chunk also changes. In this case, you will have to separate out DML as well. Depending on the use case you can also use Async transaction to divide DML as doing multiple DML in a single context may not be very good.

Thanks.


If you liked the post do support me by buying a pizza for me :D.





Tuesday, October 26, 2021

Lets learn Future method today!

In this post, we will try to cover the Future method. 

Note: Here we will not talk about how Queueable is better than the future method, rather we will stick to knowing about the Future method.


First things first, What is Async Apex and why do we need Async Apex in the first place? 

Async Apex is simply used to run your transaction in a different thread at a later point in time when resources are available, without your user actually waiting for it to finish. 

Assume if we could make callouts from triggers, in synchronous transaction user would have to wait for the response to come back before he could actually move ahead and that would be a terrible experience.


Luckily we have Asynx Apex methods at our disposal for such things.

There could be a few more scenarios where we might want to use Async Apex.

For example : 

  • Making callouts to an external system.  
  • Mixed DML error (We will learn later with an example) 
  • Any complex calculation which might require more governor limits.


Future methods are more like fire and forget methods as we don't know when this method will be actually executed in the future. And unlike other async apex methods, it doesn't return a job Id which we could have used to track the status.

Syntax 



Important points : 

  • We need to use @future annotation to mark any method as future.
  • We can't have any return type on future methods because these methods are executed when resources are available in future time, if we were to have a return type then the transaction would stop there and wait for returned value.
  • We can only pass primitive arguments to a future method for example String, Integer, List<String> etc. 
  • We cant pass non-primitive arguments like Sobjects as the state of records could change by the time future method is actually executed and we could end up overwriting the record. 
  • The best way would be to pass List<Id> and then query them to get the latest copy of the record.
  • The order of execution of multiple future methods is not defined. 
  • We cant call a future method from another future method ie chaining is not allowed.If you try to do that you will face an error as "Future method cannot be called from a future or batch method"
  • We also can't call from batch class, hence its always advisable to put a check before calling future method like below : 
             If( ! System.isFuture() && !System.isBatch()){
                  // Call your future method here
               }
  • When looking at debug logs you will see "FutureHandler" in the operation for debug logs, makes it easy to look at debug for future method specifically.
  • We can call a future method from Queueable Class and can also call queueable class from future method, well if you are thinking can we also do Future-> Queueable -> Future then yes we can do it and no error will be thrown.

The following is a skeletal example of a future method that makes a callout to an external service. Notice that the annotation takes an extra parameter (callout=true) to indicate that callouts are allowed


Did you know?    

  • As we discussed it's not allowed to pass non-primitive data types but still if we want to, we can simply serialize the data which will convert it into String then pass into the method.
Note: Not advisable to do, you should always pass the record id and then query to get a fresh copy.
  • Similarly, if you want to pass wrapper to your future method you can serialize it and pass it then deserialize it inside the future method.
  • Future methods are only called if a sync transaction succeeds, in case a sync transaction fails, the future method will never be even executed.
  • But in case of future method fails sync transaction will not roll back, considering both are running in different threads any exception in the future transaction will only roll async transaction.
  • Similarly in the case of the future method is being called inside another future method sync transaction will succeed and the only async transaction will fail and rollback. 
In the below example, the account number will get updated on all the records but contact insertion will fail in the future method as another future method is being called and hence future transaction will roll back



Let's discuss Mixed DML errors in detail now, below is what error looks like
"System.DmlException: Insert failed. First exception on row 0; first error: MIXED_DML_OPERATION"

This error occurs when you try to do DML on both setup and non-setup objects in a single transaction
Now comes the question what are setup and non-setup objects actually? 

Any object which impacts sharing settings in the system ie insert or update of any entity which will lead to re-calculation of sharing is considered as a setup object. For example User,Group,QueueSobject etc.

Note : If you insert a User record with Role defined will cause this error while a User record without a Role will not lead to a Mixed DML error as sharing will not be impacted if the Role is blank.

Similarly, if you just insert a group in apex along with transactional objects it will not cause issues unless you also insert Group members, as blank group ie without any member will never impact sharing.

All other transactional objects like Account, Contact are considered as non-setup object.


Example Code : 

Inserting user and Account record.



If you run this you will face a Mixed DML error. We can resolve it by simply rewriting it and moving user creation to a future method.


For limits related to Future methods please go through Salesforce document

https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_invoking_future_methods.htm


Thanks for reading...

If you liked the post do support me by buying a pizza for me :D

Sunday, June 14, 2020

Apex Percent Usage

I wanted to check on how is Apex code counted towards the limit, considering we are only allowed 6,000,000 characters (6 MB ) and we might come across a situation where we may want to increase the aforementioned limit.

Salesforce allows you to increase limit upto 10,000,000 characters (10MB) on logging a case.

Salesforce doc

I have created a few scenarios to check on what all simple things contribute towards this usage.

After creating a dummy class below is apex usage, we would run different scenarios on below class to see how is apex usage changed.

  • Adding redundant new lines (/n) in the code doesn't impact the usage.
  • Adding redundant spaces/tab in between the code increases the usage.
  • Adding redundant spaces/tab even at the end of line increases the usage.
  • Adding spaces/tabs for indentation of code also seems to increase the usage(for demo purposes I have indented class variables only)
  • Adding comments in class don't impact the usage.

  • Creating a test class don't count towards apex usage ie redundant tabs/spaces none of them are counted.

  • Blank lines containing only spaces are also not counted towards the usage.

Note : Managed packages are not counted towards the limit as they belong to different namespace as that of your org.

Thanks for reading.

If you liked the post do support me by buying a pizza for me :D


Saturday, May 30, 2020

Deep dive into Master Detail Relationships


In this post we will talk about things that are there to know related to M-D relationship.
I will try to cover things from basic to corner cases around M-D relationships.
Hopefully you will find something new in below post.
  • Owner field is not available on detail object rather it is set to owner of master record.
  • Sharing rules, manual sharing or queues cant be defined for detail object as these require owner field
  • OWD of detail object is controlled by Parent.
  • We have limit to create 40 relationship on an object and that limit can be achieved in any of below pattern. 
    • 39L 1 M
    • 38L 2 M 
    • 40L
(where L-> Lookup , M-> Master-Detail)
  • When we say an object has limit of 2 M-D its related to how many parents an object can have not how many details a parent can have.  For example Object A could be detail to Object B and Object C making it a junction object. I cant make it detail to Object D now.
  • When it comes to how many detail objects a master can have, as far as I know there is no limit, I have tested till 12 details under same master object. Do try it in your org...
  • Standard objects can't be on the detail side of a M-D relationship ie I cant even create Master detail relationship between two standard objects as that would mean one of them to be on detail side.
Let me know if you have any scenarios where you'd want to create master detail between two standard objects.
Currently there is an idea pending for enabling M-D between standard objects but not sure if it would be allowed as it would impact underlying schema,security,permissions and what not related to  objects.

Link to Idea : https://success.salesforce.com/ideaView?id=08730000000HBN2
  • You can have up to three custom detail levels ie for example  
    • Castle 
      •   Property  (Level 1)
        •   Supply (Level 2)
          •    Treasure (Level 3)
I cant create another relationship pointing to Treasure as it would void above limit.
  • We cant create master-detail relationship if the object already contains data. There are two ways to do it: 
    • We can either create a lookup field and then fill up all the records with a proper value then convert it into lookup.
    • Else we can go ahead and hard delete all the records , soft delete doesn't work as records stay in recycle bin for 15 days.
  • In a multi level relationship we cant create a roll-up field directly on grand child object ie in below scenario.
    • Castle - Parent 
      •   Property - Child 
        •   Supply - Grand child 
I cant create rollup field on Castle object to summarize data from Supply(Grand child) directly, rather I have to first create a roll on Property then create a roll up on Castle using that field on Property.
  • We cant delete an object which is master to any object.But we can delete an object which is on detail side of relationship. Here is a catch though if you at some point of time undelete the object relationship would be converted to lookup.
  • Now lets talk about deleting records in M-D relationship I have added few scenarios below: 
    • If I delete a detail record, master record stays intact and if i undelete detail record it will be linked back to master record.
    • If I delete master record all detail records will be deleted (ie including grand child records) and if I undelete the master record all the child records will also be undeleted and restored with old connections.
    • However if I delete a detail record first then delete a master record. Now if I undelete master record it will be restored back but without detail record and there is no way restore detail record now.
  • We can create cross object workflow in case of master detail relationship ie I can create a workflow on child object to update a field on parent object which is not allowed in case of lookup relationship.
  • You cant create master detail relation between custom object and User,Lead,Product,Pricebook etc you can although create lookup.
FYI : Even cascade delete option which we can get enabled from Salesforce doesn't work on object like User,Lead, Product, Pricebook.
  • A little about Junction objects (objects used to create M:M relationship) : 
    • If any of the master records are deleted junction object record will also be removed, if master record is undeleted junction object record is also restored back.
    • Deleting a junction object record doesn't delete master records.
    • First master detail created on Junction object is considered as primary relationship and if primary relationship is converted into lookup or deleted, other M-D relationship becomes primary.
    • Junction object inherits look and feel from primary relationship moreover junction object inherits value of owner from primary relationship.
    • OWD of junction object is most restrictive of both parents ie if Parent  1 is (Public Read only) and Parent2(Private) OWD of junction object will be private.
    • User must have at-least read access to both the parent records to be able to access junction object records.
    • Junction objects cant have any details objects.
Note : Above points are written assuming junction object is created with 2 M-D relationship.


Thanks for reading...

If you liked the post do support me by buying a pizza for me :D

Sunday, May 17, 2020

Insert custom parent and child record using single DML

Sometime back I came across a scenario where i wanted to insert both parent and child object records together.

There could be two ways to do it :

  • Insert parent record then insert child record using already insert parent record ID. Something similar to below. 
I noticed with this approach we will be using multiple DML statements and If I wanted to insert parent and child in bulk that would be whole another level of effort as I'd have to maintain relationship details.

  • Another way would be to create a reference of parent record and use it to set foreign key reference on child record, once done insert both parent and child in single DML.

Refer to below link for more information.
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_dml_foreign_keys.htm

I have created code snippet to do same for custom objects, make sure you read through comments to learn about general errors that might come.


Note above method will not work if you try to reference another record of same object type for example if you try to create both ParentAccount and Child Account in same transaction and try to link them using ParentId field, It will not work. In Self lookup scenarios you can only reference records which are already existing else divide them in different DML's


Thanks for reading...


If you liked the post do support me by buying a pizza for me :D