2

Assume that I have a VisualForce page that looks like this:

<apex:page controller="SearchResultController" action="{!storeSearchResults}" id="SearchResultsView">

<apex:repeat value="{!currentResults}" var="cr" id="theRepeat">
  <div class="company_profile"> 

<a href="#" class="import_button" onClick="callImport('{!cr[profile_type]}', '{!cr.get('profile_id')}'); return false;">
  Import?
</a>

<apex:outputText value="{!cr[name]}" id="companyName"/><br/>
    <apex:outputText value="{!cr[address]}" id="address"/><br/>

<apex:outputText value="{!cr[headquarters_phone_area_code]}" id="headquarters_phone_area_code"/>    
<apex:outputText value="{!cr[headquarters_phone]}" id="headquarters_phone"/> / <apex:outputText value="{!cr[website]}" id="website"/><br/>
<apex:outputText value="{!cr[industry]}" id="industry"/>

<h3>Summary:</h3>

<apex:outputText value="{!cr[description]}" id="description"/>

  </div>

</apex:repeat>

And assume I have a controller that looks sort of like this (I'm cutting some of the code because it gets boring):

public class SearchResultController {

    public List<Map<String, String>> currentResults { get; set; }

    public void storeSearchResults() {
    // the search term was saved as the Name field of the Search object, on the previous page
        String response = fetch(currentSearch);
    List<Map<String, Object>> possibleSearchResults = (List<Map<String, Object>>)deserializeJson(response);
    currentResults = formatSearchResults(possibleSearchResults);
    }

public List<Map<String, String>> formatSearchResults(List<Map<String, Object>> possibleSearchResults) {
List<Map<String, String>> formattedSearchResults = new List<Map<String, String>>();

for (Map<String, Object> possibleSearchResult : possibleSearchResults) {
    if (!possibleSearchResult.containsKey('bad_api_call')) {  
    Map<String, String> oneSearchResult = formatThisSearchResult(possibleSearchResult);
    formattedSearchResults.add(oneSearchResult);
    }
}

return formattedSearchResults; 
}


 public Map<String, String> formatThisSearchResult(Map<String, Object> unformattedSearchResult) {
Map<String, String> formattedResult = new Map<String, String>();


formattedResult.put('name', (String)unformattedSearchResult.get('name'));
formattedResult.put('profile_id', (String)unformattedSearchResult.get('profile_id'));
formattedResult.put('profile_type', (String)unformattedSearchResult.get('profile_type'));
formattedResult.put('profile_classification', (String)unformattedSearchResult.get('profile_classification'));
formattedResult.put('permalink', (String)unformattedSearchResult.get('permalink'));
formattedResult.put('location', (String)unformattedSearchResult.get('location'));

// cutting some code here

String currentSearchId = (String)currentSearch.ID; 
formattedResult.put('current_search_id', currentSearchId);

return formattedResult; 
}

You get the idea.

When I do this:

 <apex:repeat value="{!currentResults}" var="cr" id="theRepeat">

I assume that "cr" is now a map and so I can do this:

 {!cr[profile_type]}

but instead I get this error:

Unknown property 'SearchResultController.profile_type'

Why SearchResultController? That is the controller, but what would make Salesforce think I'm reference the controller itself? current_results is a public variable in SearchResultController, but "cr" is not.

What is going on?

1 Answer 1

4

Because your key should be a string, not a property. You are referencing a property (that doesn't exist) with the syntax you have used. It's the same as the difference between merging {!profile_type} (property) and {!"profile_type"} (literal string).

Change your merge syntax to use strings instead of variables. Note that you should always use JSENCODE on strings you plan to use in Javascript.

onClick="callImport({!JSENCODE(cr['profile_type'])}, {!JSENCODE(cr.get('profile_id'))}); return false;"

Alternatively (though this would be a silly thing to do), you could define the property profile_type if you want to use it the way you have it. You would need to define a property on your controller like so:

public String profile_type { get { return 'profile_type' } }

There are many syntactic variations, but again, it's a silly thing to do and I recommend you simply stick to literal strings.

You must log in to answer this question.

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