-2

I'm checking the incoming value whether exist in custom metadata or not . If the incoming value exist in custom metadata record returns TRUE otherwise returns FALSE. kindly please here how to avoid this error .

Original Code:

public static boolean fetchBICCode(String IoCaseOrgid){
    IO_Case__c lstIoCases = [Select Id, Name, Onboard_BIC_Code__c, Onboard_CareQualityCommission__c From IO_Case__c 
                             WHERE io_Organisation_ID__c = :IoCaseOrgid LIMIT 1];
    
    Boolean res = false;
    List<OnboardingBICCode__mdt> bicCodeList = [SELECT Id, Label, BicCode__c FROM OnboardingBICCode__mdt];
 
    if(bicCodeList.size() > 0){
        for(onboardingBICCode__mdt m :bicCodeList){
            System.debug('Metadata Bic Codes---->'+m.BicCode__c);//returns null
            System.debug('Onboard_BIC_Code__c---->'+lstIoCases.Onboard_BIC_Code__c);//getting value
            
            // Here I'm getting dereference null object error 

            if(m.BicCode__c.contains(lstIoCases.Onboard_BIC_Code__c)){
                System.debug('Test3---->');
                res = true;
            }
        }
    }

    system.debug('res'+res);
    return res;
}

Updated Code:

public static boolean fetchBICCode(String IoCaseOrgid){
    IO_Case__c lstIoCases = [Select Id, Name, Onboard_BIC_Code__c, Onboard_CareQualityCommission__c From IO_Case__c 
                                 WHERE io_Organisation_ID__c = :IoCaseOrgid LIMIT 1];

    Boolean res = false;
    Set<String> bicCodeSet = new Set<String>();
    List<OnboardingBICCode__mdt> bicCodeList = [SELECT Id, Label, BicCode__c FROM OnboardingBICCode__mdt];
    for(onboardingBICCode__mdt m :bicCodeList){
        bicCodeSet.add(m.BicCode__c);
    }

    bicCodeSet.remove(null);
    res = bicCodeSet.contains(lstIoCases.Onboard_BIC_Code__c);
    if(res){
        System.debug('Test3---->');
        res = true;
    }
            
    system.debug('res:::::---->'+res);
    return res;
}
1
  • A note for others that look at this question. There is no need to check the size of a collection before iterating over it. As long as the collection is not null (and a query will never give you a null list), it's fine. If a collection is empty, the loop will just simply not run.
    – Derek F
    Feb 27 at 14:17

1 Answer 1

5

We get a Null Pointer Exception (NPE) whenever you try to use dot-notation (to call a method or access a variable) on something that is null.

e.g.

// Declared, but not initialized, so c is null
Case c;
// null.(anything else) = NPE
System.debug(c.Subject);

// Again, declared but not initialized
String s;
// Again, null.(anything else) = NPE
System.debug(s.contains('some string'));

So avoiding and resolving NPEs is a game of figuring out:

  • What in this particular statement can be null
  • How do we detect/handle the null

You've already figured out what is null here (the BicCode__c field on at least one of your Custom Metadata Type records). There are multiple ways to handle the null value.

One common way to do this is to use a guard statement. I.e. check for the troublesome condition before you do the real work.

for(onboardingBICCode__mdt m : bicCodeList){
    // isBlank() is the preferred way to handle potentially null strings because
    //   it also checks for an empty string
    if(String.isBlank(m.BicCode__c)){
        // "continue" tells us to stop working on this iteration of the loop and
        //   just move on to the next iteration
        continue;
    }

    // m.BicCode__c is guaranteed to not be null once we reach this point
    if(m.BicCode__c.contains(lstIoCases.Onboard_BIC_Code__c)){
        // do work
    }
}

Personally, I like to use Maps and Sets to do comparisons like this. While it does take an imperceptible amount of extra time to run, it's usually less typing and keeps code more un-indented (too much indentation makes code hard to read/follow).

Set<String> bicCodeSet = new Set<String>();

for(onboardingBICCode__mdt m : bicCodeList){
    // Since we aren't doing anything directly with these strings, having
    //   a null value is not a concern in this approach
    bicCodeSet.add(m.BicCode__c);
}

// ...but if you're feeling paranoid, you can simply remove the null
//   using the .remove() method
bicCodeSet.remove(null);

res = bicCodeSet.contains(lstIoCases.Onboard_BIC_Code__c);
3
  • Do note that both String.contains() and Set.contains() are case-sensitive. If that's an issue, then you can either use String.containsIgnoreCase() in the first approach, or apply upper/lower casing to everything (e.g. m.BicCode__c.toLowerCase(), lstIoCases.Onboard_BIC_Code__c.toLowerCase()) in either of my two approaches.
    – Derek F
    Feb 27 at 14:53
  • I have updated the code as you suggested but still have same issue. Loop returns FLASE even I have pass the existed value in metadata .Please suggest
    – Nitish
    Feb 27 at 15:06
  • @basha You need to have an idea of what values are in the set (use a system.debug() for that, possibly in combination with JSON.serialize()) and what value lstIoCases.Onboard_BIC_Code__c holds. Keep in mind my note about case sensitivity.
    – Derek F
    Feb 27 at 15:10

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .