Podcast #128: We chat with Kent C Dodds about why he loves React and discuss what life was like in the dark days before Git. Listen now.
12

Apex Code is single-threaded. This means that your code runs sequentially, from top to bottom, until the end of the method. If you have validation occurring first, followed by other updates, your code will run to its end. Once it ends, if any records received an error (via addError), and allOrNone is "false", then those records are set aside, any work done ...


11

Suppose you have a custom object Custom_obj__c Trigger.New means it is a List<Custom_obj__c> and Trigger.NewMap means it is a map<Id, Custom_obj__c> In before insert context your Trigger.NewMap will always be null because in before context records are not submitted to the database, so the Id is not generated yet. That's why in before insert ...


10

It is quite possible, and in fact recommended (if you need trigger logic on both events). See also: Trigger Frameworks and Apex Trigger Best Practices Triggers (Apex Developer Guide) A common pattern is to have three separate layers of code: the trigger itself, a handler, and a service layer. Here's the trigger framework I prefer. Trigger trigger ...


9

You can add an error to a specific field using the addError method as follows: SObject someRecord; someRecord.SomeField__c.addError('Custom Message'); //or someRecord.someField__c.addError(someException); Note that you cannot add it to a field dynamically. This error mapping can only be done with a hard-coded field. See also: Provide an additional ...


9

== is for equality checks, = is for assignment. As such: If (soAccount.ISLock__c = True){ will assign the value of true to IsLock__c, and this statement will always be true. For this reason, I always recommend that you avoid comparing to true/false values, because it can prevent typos like this from compiling. If (soAccount.IsLock__c){


8

This is a good time to learn about the Lazy Load pattern. You can write your cache in such a way that you only consume the query if you actually need the data. Now if you make a reference to this Apex Class to perform some logic that has no need for the query, you will not touch your governor limits. public with sharing class MyService { public static ...


7

I have used the below code to get the IP address of the logged/current user. Hope this helps. Thanks Map<String, String> headersMap = ApexPages.currentPage().getHeaders(); // True-Client-IP has the value when the request is coming via the caching integration. String ipAddress = headersMap.get('True-Client-IP'); if (String.isEmpty(...


7

Yes static variables are meant for same purpose . Create a static list in your helper class and use same in your before trigger and after trigger public class cachequery { public static List<Account> lstaccount= [Select Id,Name from Account LIMIT 10]; } The sample trigger to provide an idea trigger T1 on Account (before insert, after insert) { ...


7

If you care about order of execution, triggers are far from obsolete, and this consideration still offers a compelling argument for why you would choose an Apex Trigger over Process Builder. If you need to do data transformations before a Validation Rule, or before you execute cross-object logic, you should certainly still use an Apex Trigger. The thing is, ...


7

The problem is this line here: objOpp = new Opportunity(id = mapOfOpportunity.get(eachKey)[0].Id); You're adding an error to a record that exists only in memory. Errors will only surface when you use addError on a record that is inside of Trigger.new or Trigger.old. You probably want to use the following code instead: objOpp = mapOfOpportunity.get(...


6

trigger.new is simply a list of the records being processed by the trigger, so if all you need to do is loop through them then you can use that. trigger.newMap just allows you to target specific records by Id should you not need to process everything, or if you need to map other records back to these.


6

I just checked lastmodified by id is null on a before insert event and this makes sense. For example (hastily written trigger based approach, not best practice!): trigger eventTrigger on Event (before insert) { system.debug(logginglevel.WARN, '^^^ event last modified: '+trigger.new[0].LastModifiedById); system.debug(logginglevel.WARN, '^^^ userinfo:...


6

You can't set cross object fields on trigger context records. When you specify Case__r on a record in your trigger.new collection, it is null. Hence trying to set its Status results in an attempt to de-reference a null variable. for (Accounting_Instructions__c record : trigger.new) { // below is the same as record.Case__r.Status = 'Open' Case ...


6

Yes and no No need for seperate block for update and insert they are doing almost (thanks DerekF for pointing out the additional if) the same thing and they can be consolidated pretty efficiently. Also if (doctorIds != null && doctorIds.size() > 0) { list < Bank_Account__c > banklist = [select Id, Name, Doctor__c, Category__c from ...


6

It isn't working because the Asset Id field is null in the before insert context. Records do not have Ids until after insert. Beyond that, you're updating an Account record in your Asset trigger, but you aren't performing a DML update for those Accounts. You can only avoid DML in triggers in before contexts on the same SObject (so in your Asset trigger, ...


6

This is happening because Trigger.new is not available on before delete context. You'll want to use Trigger.old instead. Check this document about Trigger Context Variables.


6

The problem is that you are calling addError on Trigger.OldMap instead of Trigger.NewMap. When declaring the signature for checkForStageDuration you have it (oldMap, newMap) but when you are passing in parameters in your trigger, you are passing in (newMap, oldMap).


6

You're seeing recursion because your recursion guard is in the wrong place. When this gets executed: AankoopDetailTriggerHandler.isBeforeInsert(trigger.new); if(AankoopDetailTriggerHandler.aankRecursion) return; AankoopDetailTriggerHandler.aankRecursion = true; what happens is something like this: Insert goes off before ...


5

Your trigger can't work with "before insert", because you can't query for records that haven't been assigned an Id, which won't happen until "after insert". You'll probably want to start of like this: trigger X on Y (after insert, before update) { if(Trigger.isInsert) { update Trigger.new.deepClone(true); return; } // Rest of ...


5

You are trying to add the Id of an Order to OrderIds before you insert the orders. sObjects don't have Ids before you insert them* I'd suggest taking your insert OrderToInsert; DML statement outside of the for loop. Then, after you insert your new orders, loop through your OrderToInsert list, and add the Ids to OrderIds at that point. *Well...they can if ...


5

Judging by the exception, I'd say that the problem is that you are running this code on an older version of the api that doesn't support the Approval.lock() method. In a different post, I found that for some reason the code will compile and gives a runtime error. If for some reason the lock methods weren't intended to work on trigger context variables, the ...


5

Your expression is almost correct. I would use <a.+<\/a>. You don't know if href will be the first property (or if there will be multiple spaces after a), and you don't want to skip links that don't conform to your definition if you can avoid it. Another thing you need to correct is to actually instantiate a Pattern (not a Matcher). Pattern ...


5

You can just query the PricebookEntry records instead: Set<Id> entryIds = new Set<Id>(); for (QuoteLineItem item : trigger.new) entryIds.add(item.PricebookEntryId); Map<Id, PricebookEntry> entries = new Map<Id, PricebookEntry>([ SELECT UnitPrice FROM PricebookEntry WHERE Id IN :entryIds ]); for (QuoteLineItem item : trigger.new) ...


5

they will execute linear in your trigger. So: public void beforeUpdate( sObject oldObj, sObject newObj ){ // will execute first method1( oldObj, newObj ); // will execute second method2( oldObj, newObj ); } If you use a trigger factory to call a trigger handler and execute bulk methods first, you will see the bulk execution pass your ...


5

See Case IsClosed Trigger Bug? This is not a bug. Currently the setting of this value is not done until the save which comes after the before trigger in the event timeline. There are two workarounds available for you I believe: 1) Execute your logic in an after trigger. This occurs after the save and thus the value should be set. 2) Query ...


5

Id fields are always indexed. It's not possible to get a non-selective query except in some esoteric cases where you have really huge data skew or lots of null values, but you'd almost certainly run into other limits (e.g. the 50,000 row limit) first. In addition, trying to filter for a field with null values when the field cannot possibly be null (Master-...


5

Others have covered how to address the Null Pointer Exception (NPE for short). I'd like to cover how to determine the cause of an NPE. When debugging NPEs, I like to keep in mind the famous saying of Sir Arthur Conan Doyle's Sherlock Holmes when you eliminate the impossible, whatever remains, however improbable, must be the truth An NPE occurs when you ...


5

Triggers are supposed to work that way. They do not pre-populate data on the screens but only update it during the transaction. Out of the box, you will not be able to pre-populate data. If you can create some lightning component, then you can utilize force:createRecord event here which lets you to open the standard screen for record creation with an option ...


5

If I understand your question correctly, then you actually can take your related record update logic and put it in either a before or after trigger. Salesforce's suggestion is that before triggers should be used to update data on the records taking part in the trigger (the ones stored in trigger context variables), but it's just that... a suggestion. ...


5

You will need to use Trigger.old in case of delete operation to be able to display your custom error message. This is from the Trigger Exceptions documentation (emphasis mine): Triggers can be used to prevent DML operations from occurring by calling the addError() method on a record or field. When used on Trigger.new records in insert and update triggers, ...


Only top voted, non community-wiki answers of a minimum length are eligible