2

I'm trying to display a chronological list of CaseHistory records to display case edits. I have the following code:

public Map<CaseHistory,String> getHelpdeskHistory() {


    List<CaseHistory> historyList = new List<CaseHistory>();

    historyList = [SELECT Case.Subject , CreatedById, OldValue, NewValue, Field, CreatedDate  FROM CaseHistory ORDER BY CreatedDate DESC];

    Map<CaseHistory, String> mapCaseToEditor = new Map<CaseHistory,String>();

    for(CaseHistory ch: historyList){

            User caseEditor = new User();

            caseEditor = [select Name from User where id = :ch.CreatedById];

            mapCaseToEditor.put(ch, caseEditor.Name);

    }

    return mapCaseToEditor;
}

The CreatedById is the ID of the user who edited a case. I'm retrieving them ordered by CreatedDate, but I need to attach a name to display it on my visualforce page.

However, due to the map being unordered, I can't figure out a better way to preserve the order returned by the query. This is how I display it in the VF page:

<apex:repeat value="{!HelpdeskHistory}" var="C">
     {!HelpdeskHistory[C]} edited {!C.Field}
</apex:repeat>

This works and displays the person who edited the case, but it's not in CreatedDate order. Is there any way I can attach a name to an ordered list and display it in VF?

1

Let me clarify a few things here:

  • Don't write SOQL queries inside a for loop
  • You can get related fields from the user [CreatedBy.Name]
  • If you want to preserve the order of elements in your map, you'll need to keep an index as a key (or other primitive type)
  • You can have all your data in a wrapper class mapped to an index

So your code should look something like this:

public class CaseHistoryWrapper
{
    public String field {get; set;}
    public String editedBy {get; set;}

    public CaseHistoryWrapper(String field, String editedBy)
    {
        this.field = field;
        this.editedBy = editedBy;
    }
}

public Map <Integer, CaseHistoryWrapper> getHelpdeskHistory()
{
    Map <Integer, CaseHistoryWrapper> result = new Map <Integer, CaseHistoryWrapper> ();

    Integer index = 0;

    for (CaseHistory caseHistory : [SELECT Case.Field, CreatedBy.Name FROM CaseHistory ORDER BY CreatedDate DESC])
    {
        result.put(index, new CaseHistoryWrapper(caseHistory.Case.Field, caseHistory.CreatedBy.Name));
        index++;
    }

    return result;
}

Then in your VF you iterate through the keys of the map (indexes) and you can easily reference all the data corresponding to a specific index:

<apex:repeat value="{!HelpdeskHistory}" var="index">
    {!HelpdeskHistory[index].editedBy} edited {!HelpdeskHistory[index].field}
</apex:repeat>

Disclaimer: I wrote this code on the fly and it might not 100% work, but this is the approach I would be taking to solve this problem.

Your Answer

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