I am creating a component to add to a contact record that shows aggregated note data from two different sources.


<apex:page id="AggergatedNotes"
    <c:AggergatedNotes notes="{!wrapper}" />


public with sharing class AggregatedNotesController {
    private Case theCase;
    private Contact theContact {get; set;}
    public List<Wrapper> wrappers {get; set;}

    public AggregatedNotesController (ApexPages.StandardController stdController) {
        List<String> Contacts = new List<String>();
        List<Wrapper> wrappers = new List<Wrapper>();

        if (ApexPages.currentPage().getParameters().get('id').startsWith('003') ) {
            this.theContact = (Contact) stdController.getRecord();
            this.parentId = theContact.Id;
            Contacts = Utilities.GetExternalContacts(theContact.Id, 'Ent');
        } else {
            stdController.addFields(new List<String> {'Contact.Id'});
            this.theCase = (Case) stdController.getRecord();
            this.parentId = theCase.Contact.Id;
            Contacts = Utilities.GetExternalContacts(theCase.Contact.Id, 'Ent');
        if (Contacts.size() > 0) {
            List<Event__x> events = [
                WhoId__c IN :Contacts
                ORDER BY EndDateTime__c DESC

            List<Task__x> tasks = [
                WhoId__c IN :Contacts
                ORDER BY ActivityDate__c DESC

            for (Event__x ev: events) {
                wrappers.add(new Wrapper(ev) );
            for (Task__x ta: tasks) {
                wrappers.add(new Wrapper(ta) );
    public class Wrapper {
        public Event__x evt {get; set;}
        public Task__x tsk {get; set;}
        public String comments {get; set;}
        public String ownerId {get; set;}
        public String ownerName {get; set;}

        public Wrapper(Task__x t) {
            tsk = t;
            comments = tsk.Description__c;
            ownerId = tsk.OwnerId__r.Id;
            ownerName = tsk.OwnerId__r.Name__c;

        public Wrapper(Event__x e) {
            evt = e;
            comments = evt.Description__c;
            ownerId = evt.OwnerId__r.Id;
            ownerName = evt.OwnerId__r.Name__c;


<apex:component id="AggregatedNotes" controller="AggregatedNotesComponentController">
    <apex:attribute name="notes" type="Wrapper" description="The Aggergated Notes List" assignTo="{!wrappers}"/>
   ... Will render table here ...

Component Controller

public with sharing class AggregatedNotesComponentController {
    // Not sure how to get the wrapper data here

From what I understand, I need to use the standard controller and then extend my apex class.

Since I am using the two different sources of data, I believe I need to use a wrapper to combine them for my visualforce page.

My main issue is that I don't know now how to pass the data from the page to the component so that I can render it.

Within the component where I assign it to an attribute, it also requires a type (<apex:attribute name="notes" type="...") and I wasn't able to get Wrapper to work. Unsure what other type this would be.

I'm sure I am way off on this, but hoping to get some feedback on how to approach this structure.

  • Because Wrapper is an inner-class of AggregatedNotesController I believe your Visualforce component will need a type of AggregatedNotesController.Wrapper. You can eliminate the verbosity by turning Wrapper into its own class. – nbrown Jan 7 at 16:20
  • @nbrown What would I need to define in AggregatedNotesComponentController in order to get access to this from the extended controller? Right now its blank, and this is controller that the component is referencing for that apex:attribute. – SBB Jan 7 at 18:28
  • 1
    Right now you're assigning the apex:attribute to {!wrappers} but it doesn't exist in your component controller. Create it, and it should be assigned correctly. Check out the Visualforce Component documentation here: developer.salesforce.com/docs/atlas.en-us.pages.meta/pages/… – nbrown Jan 7 at 18:37
  • @nbrown - Thanks, that's where my confusion is coming from. My page controller has all of that functionality where the wrapper exists. Its either in the wrong place or I need to have it in both I guess. – SBB Jan 7 at 19:04

Your Answer

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

Browse other questions tagged or ask your own question.