2

I tried following the instructions listed here: How to handle maps with no key match but I can't seem to get it work since Postal_Code__c is my key. Right now, everything works as long as the Postal Code is blank or in the TimeZone__c custom setting. If the zip is invalid, the page throws an error.

Map key 00001 not found in map Error is in expression '{!zipToTimeZoneMap[activeOpp]}' in component

Am I just missing an IF statement?

public with sharing class PageController {
    public List<Opportunity> activeOpps { get; set; }
    public String localTime{get;set;}
    public Map<String, String> zipToTimeZoneMap {get;set;}
    public boolean render{get;set;}

    public PageController(ApexPages.StandardController controller) {
        sortDirection = 'ASC';
        sortExp = 'Name';
        loggedInUserId = UserInfo.getUserId();
        activelyWorkingoppsData = new List < Opportunity > ([SELECT id, Name, Account.Phone, StageName, Postal_Code__c 
                                                             FROM Opportunity 
                                                             WHERE(ownerId = : UserInfo.getUserId() limit 10]);

        zipToTimeZoneMap = new Map < String, String > ();

        String timeDiff;
        integer d;
        TimeZone__c tz = new TimeZone__c();

        for (Opportunity o: activeOpps) {

            If(zipToTimeZoneMap.keyset().contains(o.postal_code__c) == true) {
                timeDiff = zipToTimeZoneMap.get(o.postal_code__c);
                System.debug('o.postal_code__c=================>' + o.postal_code__c);
                //      tz = TimeZone__c.getValue(o.postal_code__c);
                System.debug(tz);

                if (tz != null) {
                    d = integer.ValueOf(tz.TimeDiff__c);

                    System.debug('integerD===========>' + d + 'integerTZ===' + tz);
                    localTime = system.Now().addHours(d).format('h:mm a');
                    zipToTimeZoneMap.put(o.postal_code__c, localTime);
                    System.debug('zipToTimeZoneMap=================>' + zipToTimeZoneMap);
                }
            }
        }
        public String sortExpression {
            get {
                return sortExp;
            }
            set {
                if (value == sortExp) sortDirection = (sortDirection == 'ASC') ? 'DESC' : 'ASC';
                else sortDirection = 'ASC';
                sortExp = value;
            }
        }
        public PageReference ViewActivelyWorkingoppsData() {
            try {
                string sortFullExp = sortExpression + ' ' + sortDirection;
                activeOpp = Database.query('Select id,Name, Account.Phone,StageName, From Opportunity where ownerId=:loggedInUserId ' + localTime + ' order by ' + sortFullExp + ' limit 10 ');
                return null;
            } catch (Exception ex) {

                return null;
            }
        }
    }
}

and the Vf section

<apex:column value="{!zipToTimeZoneMap[activelyWorkingoppData.Postal_Code__c]}" headervalue="Local Time" style="color:{!IF((activelyWorkingoppData.Product__c=='Instant'),'red','black')};">
    <apex:facet name="header">
        <apex:commandLink rendered="{!render}" value="Local Time>   
            <apex:param value="{!zipToTimeZoneMap[activelyWorkingoppData.Postal_Code__c]}" ></apex:param> 
        </apex:commandLink>  
    </apex:facet>                                                            
</apex:column>
  • 1
    What exactly is the error message? – Uwe Heim Feb 28 '15 at 17:52
  • The error is on the Visualforce page. If an opportunity has an invalid postal code (such as 00001) that is not in the map, the error is: Map key 00001 not found in map Error is in expression '{!zipToTimeZoneMap[activeOpp]}' in component <apex:column> – user17496 Feb 28 '15 at 18:18
  • 1
    you should check first in the map whether key exist or not, if(zipToTimeZoneMap.containsKey(zipcode)) – Harshit Feb 28 '15 at 18:26
  • Could you show us your wrapper class? If you're not using one, I can readily see where you can add a method to at least isolate the postal_code__c values not contained in your map's keyset. – crmprogdev Feb 28 '15 at 18:28
  • @crmprogdev I am not using a wrapper class. – user17496 Feb 28 '15 at 18:39
2

Since you're not using a wrapper class, you need to filter out any opps where o.postal_code__c isn't contained in zipToTimeZoneMap.keyset(). To do that, add an if statement to your code as follows to remove any opps not supported by your map:

    String timeDiff;
    integer d;
    TimeZone__c tz = new TimeZone__c();

    for(Opportunity o :activelyWorkingoppsData)
    {

        If(zipToTimeZoneMap.keyset().contains(o.postal_code__c) == true && zipToTimeZoneMap.get(0.postal_code__c) != null) {
           System.debug('o.postal_code__c=================>'+o.postal_code__c);               
           System.debug('zipToTimeZoneMap.get(0.postal_code__c)=================>'+zipToTimeZoneMap.get(0.postal_code__c));               
           tz = TimeZone__c.getValue(o.postal_code__c);
           System.debug(tz);

           if(tz!=null){ 
              d = integer.ValueOf(tz.TimeDiff__c);

              System.debug('integerD===========>'+d+'integerTZ==='+tz);
              localTime = system.Now().addHours(d).format('h:mm a');
              zipToTimeZoneMap.put(o.postal_code__c,localTime);
              System.debug('zipToTimeZoneMap=================>'+zipToTimeZoneMap);
           }
        }
     }

You can collect those Opps that fail the test condition in an else statement and use a render=false or something along those lines if you need to for your page.

  • I get the same error when I try that; I added a render variable that i set to True in my loop. if(tz!=null){ d = integer.ValueOf(tz.TimeDiff__c); System.debug('integerD===========>'+d+'integerTZ==='+tz); localTime = system.Now().addHours(d).format('h:mm a'); zipToTimeZoneMap.put(o.postal_code__c,localTime); System.debug('zipToTimeZoneMap=================>'+zipToTimeZoneMap); render = true; } } else{render=false;} – user17496 Feb 28 '15 at 19:22
  • and here is the VF <apex:column value="{!zipToTimeZoneMap[activeOpp]}" headervalue="Local Time"> <apex:facet name="header"> <apex:commandLink rendered="{!render}" value="Local Time"> <apex:param value="{!zipToTimeZoneMap[activeOpp.Postal_Code__c]}" ></apex:param> </apex:commandLink> </apex:facet> </apex:column> – user17496 Feb 28 '15 at 19:24
  • I've made some edits to correct a few things, however you've not included all of your controller code. Please edit your post to include all of the controller and the VF code you've included above (edit is at bottom left). There may be an issue with tz = TimeZone__c.getValue(o.postal_code__c) where you were using getValues. The previous If statement has no effect if you then call a getter method that could call more than one o.postal_code__c which is what that statement would seem to do. – crmprogdev Feb 28 '15 at 19:55
  • I tried adding a different check, but then it throws the error for null values with no list match. – user17496 Feb 28 '15 at 21:29
  • Null values means that some of the mapkeys are returning null values, so you need to add a check to see if the value in the map is null. If it is, then that op.Id also needs to be removed from what you can return through your controller. See my edit above. – crmprogdev Feb 28 '15 at 23:12
0

I think you need a wrapper class to guard against Opportunities that don't have a postcode. However, there is a bigger issue - your map will never get any values as there is some incorrect logic: Change:

if(zipToTimeZoneMap.keyset().contains(o.postal_code__c) == true)

To:

if(zipToTimeZoneMap.keyset().contains(o.postal_code__c) == false)

i.e., in your loop, you are saying that if the Map contains the postcode key, add it. You need to be adding if it DOES NOT contain the key.

I would also likely put in a guard clause above this, by extracting the post_code__c and evaluating for null. You could do something like this:

String postCode = o.postal_code__c;
//enter if no post code has been defined
if ( (postCode == null || postCode == '' )){

    if (!zipToTimeZoneMap.containsKey('None')){
        zipToTimeZoneMap.put('None','Unknown');
    }
    continue;
}

You could even pre-populate the Map with this value outside your Opportunity which would mean you could avoid this check: !zipToTimeZoneMap.containsKey('None') inside the loop.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.