function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
SalesForceGirlSalesForceGirl 

Map key {some key} not found in map

I have been having some serious issues getting maps to work like they should in VF pages, but it seems that the functions we have to check if it has null or blank values don't really work for maps. Here is a simple example of what I am trying to do:

<apex:page showHeader="true" sidebar="true" controller="sfg_ContactPhotos">
  <apex:repeat value="{!lstOfContacts}" var="c">

    <apex:image rendered="{!ISBLANK(mapOfPhotos[c.Id])}" url="{!URLFOR($Action.Attachment.Download, mapOfPhotos[c.Id])}" width="50" height="50" />

  </apex:repeat>
</apex:page>

 Even it it wasn't an Attachment, it could be anything, the point is that the ISBLANK should see if the map has a value and if not, don't show it, instead it causes an error on the page:


Map key 003J000000T3woPIAR not found in map

Error is in expression '{!ISBLANK(mapOfPhotos[c.Id])}' in component <apex:image> in page sfg_contactphoto
 
I added a debug and the Map key is there, even though the error complains about it not being there.
 
USER_DEBUG|[42]|DEBUG|{003G0000010ItFZIA0=null, 003G0000010JMiwIAG=null, 003J000000Q0n7FIAR=null, 003J000000Q0nBGIAZ=null, 003J000000Q1E9XIAV=null, 003J000000Q1EAyIAN=null, 003J000000SfAzLIAV=00PJ0000000fM1YMAU, 003J000000Shhd2IAB=null, 003J000000T3wmxIAB=00PJ0000000fsDfMAI, 003J000000T3woPIAR=null, ...}
 
At the very least the error should say something like:
 
Map value not found in Map 
 
Regardless, is there a VF function to check maps? I am trying to give sfdc the benefit of the doubt that I am just using the wrong function, but when looking at the documentation there seems to be nothing. I even tried NULLVALUE even though its not exactly what I need since it has an alternate value instead of boolean likst ISBLANK and so can't really be used in the rendered attribute. I even tried changing it so that it wasnt an Object or Id, and to a String, but then the Attachment complains that its not the correct type of value:
 
Invalid parameter for function URLFOR
Error is in expression '{!URLFOR($Action.Attachment.Download, mapOfPhotos[c.Id])}' in component <apex:page> in page sfg_contactphoto

I also tried conveting the Id to a string for just the check since it seemed to work above:
 
<apex:image rendered="{!NOT(ISBLANK(TEXT(mapOfPhotos[c.Id])))}" url="{!URLFOR($Action.Attachment.Download, mapOfPhotos[c.Id])}" width="50" height="50" />

 but it just give the same error as the first time:

 

Map key 003J000000T3woPIAR not found in map

Error is in expression '{!ISBLANK(mapOfPhotos[c.Id])}' in component <apex:image> in page sfg_contactphoto

I can get what I need do using an alternative way, but it should work with maps. 
 
here is the controller if anyone is interested:
public class sfg_ContactPhotos {

  public List<Contact> lstOfContacts {get; set;}
  public Map<Id, Id> mapOfPhotos {get; set;}

  public sfg_ContactPhotos() {
    lstOfContacts = findContacts();
    mapOfPhotos = buildPhotoMap(lstOfContacts);
  }

  private List<Contact> findContacts() {
    return [select Name, 
                   Email,
                   (select ContentType
                    from Attachments
                    where isPrivate = false
                    order by LastModifiedDate desc)
            from Contact
            order by LastModifiedDate desc
            limit 10];
  }

  private Map<Id, Id> buildPhotoMap(List<Contact> pContacts) {
    if (pContacts.isEmpty()) {
      return new Map<Id, Id>();
    }

    Map<Id, Id> returnMap = new Map<Id, Id>();
    for (Contact c : pContacts) {
      for (Attachment a : c.Attachments) {
        if (returnMap.containsKey(c.Id)) {
          break;
        }
        if (a.ContentType.contains('image/')) {
          returnMap.put(c.Id, a.Id);
          break;
        }
      }
      if (!returnMap.containsKey(c.Id)) {
        returnMap.put(c.Id, null);
      }
    }
    return returnMap;
  }

}

 


Best Answer chosen by Admin (Salesforce Developers) 
Christopher_Alun_LewisChristopher_Alun_Lewis

Hi,

 

I believe you can use a strings to represent Ids and show images, while keeping your map intact.

 

Like so, Controller: 

 

public class sfg_ContactPhotos {

  public List<Contact> lstOfContacts {get; set;}
  public Map<String, String> mapOfPhotos {get; set;}

  public sfg_ContactPhotos() {
    lstOfContacts = findContacts();
    mapOfPhotos = buildPhotoMap(lstOfContacts);
  }

  private List<Contact> findContacts() {
    return [select Name, 
                   Email,
                   (select ContentType
                    from Attachments
                    where isPrivate = false
                    order by LastModifiedDate desc)
            from Contact
            order by LastModifiedDate desc
            limit 10];
  }

  private Map<String, String> buildPhotoMap(List<Contact> pContacts) {
    if (pContacts.isEmpty()) {
      return new Map<String, String>();
    }

    Map<String, String> returnMap = new Map<String, String>();
    for (Contact c : pContacts) {
      for (Attachment a : c.Attachments) {
        if (returnMap.containsKey(c.Id)) {
          break;
        }
        if (a.ContentType.contains('image/')) {
          returnMap.put(c.Id, a.Id);
          break;
        }
      }
      if (!returnMap.containsKey(c.Id)) {
        returnMap.put(c.Id, 'No Image');
      }
    }
    return returnMap;
  }

}

 Page code:

<apex:page showHeader="true" sidebar="true" controller="sfg_ContactPhotos">
  <apex:repeat value="{!lstOfContacts}" var="c">

    <apex:image rendered="{!mapOfPhotos[c.Id] != 'No Image'}" url="{!URLFOR($Action.Attachment.Download, mapOfPhotos[c.Id])}" width="50" height="50" />

  </apex:repeat>
</apex:page>

 This worked for me! Let me know if that helps.

 

Regards,

 

Christopher Alun Lewis.

 

see The Christopher Alun Lewis Blog for Salesforce news, comment and development tips and tricks

All Answers

Christopher_Alun_LewisChristopher_Alun_Lewis

Hi,

 

I believe you can use a strings to represent Ids and show images, while keeping your map intact.

 

Like so, Controller: 

 

public class sfg_ContactPhotos {

  public List<Contact> lstOfContacts {get; set;}
  public Map<String, String> mapOfPhotos {get; set;}

  public sfg_ContactPhotos() {
    lstOfContacts = findContacts();
    mapOfPhotos = buildPhotoMap(lstOfContacts);
  }

  private List<Contact> findContacts() {
    return [select Name, 
                   Email,
                   (select ContentType
                    from Attachments
                    where isPrivate = false
                    order by LastModifiedDate desc)
            from Contact
            order by LastModifiedDate desc
            limit 10];
  }

  private Map<String, String> buildPhotoMap(List<Contact> pContacts) {
    if (pContacts.isEmpty()) {
      return new Map<String, String>();
    }

    Map<String, String> returnMap = new Map<String, String>();
    for (Contact c : pContacts) {
      for (Attachment a : c.Attachments) {
        if (returnMap.containsKey(c.Id)) {
          break;
        }
        if (a.ContentType.contains('image/')) {
          returnMap.put(c.Id, a.Id);
          break;
        }
      }
      if (!returnMap.containsKey(c.Id)) {
        returnMap.put(c.Id, 'No Image');
      }
    }
    return returnMap;
  }

}

 Page code:

<apex:page showHeader="true" sidebar="true" controller="sfg_ContactPhotos">
  <apex:repeat value="{!lstOfContacts}" var="c">

    <apex:image rendered="{!mapOfPhotos[c.Id] != 'No Image'}" url="{!URLFOR($Action.Attachment.Download, mapOfPhotos[c.Id])}" width="50" height="50" />

  </apex:repeat>
</apex:page>

 This worked for me! Let me know if that helps.

 

Regards,

 

Christopher Alun Lewis.

 

see The Christopher Alun Lewis Blog for Salesforce news, comment and development tips and tricks

This was selected as the best answer
SalesForceGirlSalesForceGirl

humm thats weird, cause when i changed the value to a String it caused an error with the Attachement, but I tried your example and it still gives this error:

 

Invalid parameter for function URLFOR

Error is in expression '{!URLFOR($Action.Attachment.Download, mapOfPhotos[c.Id])}' in component <apex:page> in page sfg_contactphoto
 
maybe it because i am still in Spring13?
AdrianCCAdrianCC

Hi,

 

Since the problem revolves around null values in maps for VF you need to change the way you're checking for that null so that the page doesn't crash&burn. Try this: http://salesforce.stackexchange.com/questions/5190/how-to-handle-maps-with-no-key-match

 

Ty,

Adrian

SalesForceGirlSalesForceGirl

SO i got it working when i did yours word for word, it seems that i couldnt use an empty string, it had to be a word lol so this wouldnt work:

<apex:image rendered="{!mapOfPhotos[c.Id] != ''}" url="{!URLFOR($Action.Attachment.Download, mapOfPhotos[c.Id])}" width="50" height="50" />