You need to sign in to do that
Don't have an account?
fer_far
Custom components with email templates
Hi,
Is it possible to send emails with visualforce templates using custom components?
I have written an Apex controller, a custom component and a visualforce email template. In the template I'm using {!relatedTo} to pass a custom object to the component, but it seems to fail when I try to send the email with a SingleEmailMessage using the template.
Can someone help me please?
Thanks in advance.
All Answers
The error happens when I try to preview the template after saving, the error message is "Attempt to de-reference a null object". It looks like the template cannot resolve {!relatedTo}.
The same occurs when sending the email with SingleEmailMessage.
No, this is the only message shown.
I will paste the code:
The Apex controller is something like this:
public class sendOffer { public String url {get; set;} public BXES_Bid_and_Offers__c offer {get; set;} public sendOffer() { if (offer.FTES_Estado__c == 'XXXXX') { url = 'imageurl1'; } else { url = 'imageurl2'; } } }
<apex:component controller="sendOffer" access="global"> <apex:attribute name="myOffer" type="BXES_Bid_and_Offers__c" assignTo="{!offer}"/> <apex:image style="position: absolute; left: 50%; top: 11%" value="{!url}"/> </apex:component>
In the template I use the component:
relatedToType="BXES_Bid_and_Offers__c"
...
<c:sendOffer myOffer="{!relatedTo}"/>
And the email is sent from a trigger using a SingleEmailMessage object:
BXES_Bid_and_Offers__c[] OffersNew = Trigger.new; for(BXES_Bid_and_Offers__c offer: OffersNew){ Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage(); String[] addresses = new String[]{}; addresses.add(offer.FTES_Customer_Service__c); addresses.add(offer.FTES_Sales_Manager__c); if (!direcciones.IsEmpty()) { email.setToAddresses(addresses); } email.setSaveAsActivity (false); email.setTemplateId('00XS0000000IY5Y'); email.setTargetObjectId(offer.OwnerId); email.setWhatId (offer.Id); Messaging.SendEmailResult [] r = Messaging.sendEmail(new Messaging.SingleEmailMessage[] {email}); }
I hope this helps.
it does. Here's your problem:
You are referring to members on the object being passed in, offer, before the setter is actually called. The constructor is the first thing that is invoked so offer is still null at that point and referencing .FTES_Estado__c on the null offer throws the error.
In most cases we show line/column numbers for this type of error - it seems we missed that in the Visualforce email template UI/situation. I'll make sure the owner for this area is informed.
To fix this for your specific case based on what I see here, I recommend eliminating the url property and replacing it with a getUrl method. In this case your controller would look like this:
public class sendOffer { public BXES_Bid_and_Offers__c offer {get; set;} public String getUrl() { return offer.FTES_Estado__c == 'XXXXX' ? 'imageurl1' : 'imageurl2'; } }
Thank you very much for your help.
I tried your fix typing the following in my custom component (after ):
value="{!getURL()}"
or
value="{!getURL}
But both of them fail when saving. The errors shown are "getURL function unknown" and "getURL property unknown". It looks like the component does not recognize getURL method from the class.
Did I say to make any changes to your component? :smileywink:
Your binding should remain {!url} (i.e. drop the 'get').
Thanks again, I thought that was the way ...
Now, when selecting the template to send an email the error is: SObject row was retrieved via SOQL without querying the requested field: BXES_Bid_and_Offers__c.FTES_Estado__c
You need to seed your relatedTo object with a reference you need in the controller, or query in your controller for the data it needs but taking a step back, do you need a controller here at all?
This logic can be built into the template:
<apex:image style="position: absolute; left: 50%; top: 11%" value="{!IF(offer.FTES_Estado__c = 'XXXXX','imageurl1','imageurl2')}"/>
Thank you very much for your help !!!
Finally I got it. As you said, I had no need of controllers / components. I didn't know all the possibilities that templates provide since I'm not very experienced in developing with VF.
Regards.