Pages

Showing posts with label Apex. Show all posts
Showing posts with label Apex. Show all posts

Saturday, 3 October 2020

Safe Navigation Operator | Winter '21 Release

 In Winter '21 Salesforce Release, Salesforce has introduced a new operator called "Safe Navigation Operator".  This operator will help us to avoid NullPointer Exceptions and reduce lines of code and make the code more cleaner. 

This is not something new, this already exist in many other programming languages (also known as optional chaining operator, safe call operator, null-conditional operator).

the safe navigation operator is a binary operator that returns null if its first argument is null; otherwise it performs a dereferencing operation as specified by the second argument.

The main advantage of using this operator is this avoids multiple if s and else conditions.

If the left-hand-side of the chain expression evaluates to null, the right-hand-side is not evaluated. Use the safe navigation operator (?.) in method, variable, and property chaining. The part of the expression that is not evaluated can include variable references, method references, or array expressions.

Example

  • This example first evaluates a, and returns null if a is null. Otherwise, the return value is a.b.
    a?.b // Evaluates to: a == null? Null : a.b
  • This example returns null if a[x] evaluates to null. If a[x] does not evaluate to null and aMethod() returns null, then this expression throws a null pointer exception.
    a[x]?.aMethod().aField // Evaluates to null if a[x] == null
  • This example returns null if a[x].aMethod() evaluates to null.
    a[x].aMethod()?.aField 
  • This example indicates that the type of the expression is the same, whether the safe navigation operator is used in the expression or not.
    Integer x = anObject?.anIntegerField; // The expression is of type Integer because the field is of type Integer
  • This example shows a single statement replacing a block of code that checks for nulls.
    // Previous code checking for nulls
    String profileUrl = null;
    if (user.getProfileUrl() != null) {
    	profileUrl = user.getProfileUrl().toExternalForm();
    	}
    // New code using the safe navigation operator
    String profileUrl = user.getProfileUrl()?.toExternalForm();
  • This example shows a single-row SOQL query using the safe navigation operator.
    // Previous code checking for nulls
    results = [SELECT Name FROM Account WHERE Id = :accId];
    if (results.size() == 0) { // Account was deleted
        return null;
    }
    return results[0].Name;
    // New code using the safe navigation operator
    return [SELECT Name FROM Account WHERE Id = :accId]?.Name;

 See Also

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

Monday, 10 June 2019

'List has no rows for assignment to SObject' error

The following query is not returning any number of records:
"[SELECT Id FROM Account WHERE Id = :Trigger.new[0].Account__c]"
The error "List has no rows for assignment to SObject" occurs when the query doesn't return any rows.

Player__c player = [SELECT Id from Player__c where Name = :username];
if (player != null)
 p = player.Id;
The above code will fail if there is no Player__c record with the matching username. It doesn't actually return a null.

It would be safer to do the following:

Player__c[] players = [SELECT Id from Player__c where Name = :username];
if (players.size() > 0)
p = players[0].Id;
It’s one of those situations for which you would not normally think of creating a test, so it’s safer to just avoid the possibility.

Enforce Field-Level Security in Apex (Pilot)

Apex has a new security feature for field-level data protection, which is accessed through the Security and SObjectAccessDecision classes. To ensure secure processing in Apex in the context of the current user’s read, create, or update operation, use the stripInaccessible method. Based on the field-level security of the current user, this method can be used to strip the fields from query results that the user can’t access. The method can also be used to remove inaccessible fields from sObjects before a DML operation to avoid exceptions and to sanitize sObjects that have been deserialized from an untrusted source.
How: The stripInaccesible method checks the source records for fields that don’t meet the field-level security check for the current user and creates a return list of sObjects. The return list is identical to the source records, except that the fields that are inaccessible to the current user are removed.

Example
If the user doesn’t have the permission to create the Probability field of an Opportunity object, this example removes the Probability field before creating the records. The DML operation is completed without throwing an exception.


List<Opportunity> opportunities = new List<Opportunity>{
    new Opportunity(Name='Opportunity1'),
    new Opportunity(Name='Opportunity2', Probability=95)
};

// Strip fields that are not creatable
SObjectAccessDecision decision = Security.stripInaccessible(
    AccessType.CREATABLE,
    opportunities);

// Print stripped records
for (SObject strippedOpportunity : decision.getRecords()) {
    System.debug(strippedOpportunity);
}

// print modified indexes
System.debug(decision.getModifiedIndexes());

// Print removed fields
System.debug(decision.getRemovedFields());

//System.debug Output
// DEBUG|Opportunity:{Name=Opportunity1}
// DEBUG|Opportunity:{Name=Opportunity2}
// DEBUG|{1}
// DEBUG|{Opportunity={Probability}}