0

I'm building a trigger that everytime a Campaign Member is added , Salesforce sends an email to the Owner of the Account where the Contact Lives that a Campaign Member is added.

Due to Salesforce governor limits I can query my way through the data, so I'm storing the data on Lists of Ids, Contacts, Accounts and Users.

I want now to create, based from that Data, a List that would look like a table with Rows and Columns. Something like these:

Info[0]='Contact Id', 'Account Id' ,'UserId','User Email'

Info[1]='Contact Id', 'Account Id' ,'UserId','User Email'

Info[2]='Contact Id', 'Account Id' ,'UserId','User Email'

Info[3]='Contact Id', 'Account Id' ,'UserId','User Email'

Right now I'm using this:

List<List<string>> lists = new List<List<string>>();

And thought(Incorrectly) that I could just add the info like this:

lists[0][0] = ContactId;
lists[0][1] = AccountId;

Using this method I'm getting the error: List index out of bounds: 0

Hope you can help me.

2
  • Made a typo. It should said 'I want NOW to create' insted of 'I want not to create'
    – ErFran
    Commented Apr 17, 2019 at 6:27
  • If you want to aggregate data like that a wrapper class is normally a good way to go, any reason you haven't used one?
    – Girbot
    Commented Apr 17, 2019 at 7:21

1 Answer 1

2

To resolve your issue you simply need to ensure that you have actually created the lists themselves. Remember that a list is just another type of object, so is held by reference, and that reference can be null.

You need to do something like:

if (lists == null) {
    lists = new List<List<String>>();
}

lists.add(new List<String> {
        ContactId, AccountId, UserId, UserEmail
    });

I would, however, suggest you actually manage a list of object instances. You can declare yourself a nested class like:

public class TheMainClass {
    public class EmailDetail {
        public Id contactId { get; set; }
        public Id accountId { get; set; }
        public Id userId { get; set; }
        public String userEmail { get; set; }

        public EmailDetail(Id contactId, Id accountId, Id userId, String userEmail) {
            this.contactId = contactId;
            this.accountId = accountId;
            this.userId = userId;
            this.userEmail = userEmail;
        }
    }

Your list would be like:

List<TheMainClass.EmailDetail> emailDetails = new List<TheMainClass.EmailDetail>();

Then later in your code you can add new entries to your list:

emailDetails.add(new TheMainClass.EmailDetail(contactId, accountId, userId, userEmail));

The big benefits here are that:

  1. Accessing the data is like emailDetails[n].contactId rather than lists[n][0]
  2. The various properties are strongly typed, so you can only put an Id in the ID values

I might even take it a step further and consider using a map, indexed by target user ID, of slightly different details if I wanted to ensure that a given user only received a single email with the detail of the contacts across all relevant accounts.

You must log in to answer this question.

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