I have created a simple visualforce email template:

<messaging:emailTemplate subject="** Inventory Wishlist Match Found **" recipientType="User" relatedToType="Inventory_Wishlist__c">
<messaging:htmlEmailBody > 

Year: {!relatedTo.Year__c}<br />
Make: {!relatedTo.Make__c}<br />
Model: {!relatedTo.Model__c}

<p>Below is a link to your request and the matching inventory.</p>

Request: <a href="http://cs11.salesforce.com/{!relatedTo.Id}">{!relatedTo.Name}</a><br />
Inventory: <c:ProductLinkComponent yearValue="{!relatedTo.Year__c}" makeValue="{!relatedTo.Make__c}" modelValue="{!relatedTo.Model__c}" />


Here is my component:

<apex:component access="global" controller="ProductLinkController">

<apex:attribute name="yearValue" description="Attribute for product year" type="String" required="required" assignTo="{!year}" />
<apex:attribute name="makeValue" description="Attribute for product make" type="String" required="required" assignTo="{!make}" />
<apex:attribute name="modelValue" description="Attribute for product model" type="String" required="required" assignTo="{!model}" />

<a href="http://cs11.salesforce.com/{!productId}">{!productName}</a>


Here is my component controller:

public class ProductLinkController {

public Product2 product {
    get {
        List<Product2> productList = [select Id, Name from Product2 where year__c =: year AND Make__c =: make and Model__c =: model limit 1];
        if(!productList.isEmpty() && product == null) {
            product = productList[0];
        else {
            product = new Product2();
        return product;
public String year { get;set; }
public String make { get;set; }
public String model { get;set; }

public ProductLinkController() {


public String getProductId() {
    return product.Id;

public String getProductName() {
    return product.Name;

I'm trying to output a link to a product in my email based on the values (year, make, model) that are passed thru the email template to the controller.

The query is not returning the correct product and I'm having problems debugging the component controller to see the values that are getting passed in.

Any help is appreciated. Thanks.

1 Answer 1


The reason it's not working as intended has to do with the order of execution for page loads

The controller constructor is executed before the class properties are set (year, make, model). So the bind variables in the SOQL query in the constructor are all null when the constructor executes. THEN, year make and model are set from the values on the page.

One way to remedy this is in the component controller, move the SOQL query to a getter on the product variable.

private final Product2 product {
   get {
      product = [select Id, Name from Product2 where year__c =: year AND Make__c =: make and Model__c =: model limit 1];
      return product; }
  • I tried modifying my component controller with the change you suggested (see above), but I'm getting the error List has no rows for assignment to SObject.
    – Dman100
    Commented May 16, 2014 at 16:04
  • In the email template's call to the component, right curly brackets are missing in the value assignments, so your literally passing "{!relatedTo.Year__c" and not the wishlist field value. But this does bring up a best practice issue that I lazily neglected regarding the query. You should assign the query result to a list of product2's as opposed to a product2 because it won't error out if no records are found.
    – jabbo
    Commented May 17, 2014 at 16:30
  • get { List<Product2> lstProduct = [query...]; if (!lstProduct.isempty() && product == null) product = lstProduct[0]; }
    – jabbo
    Commented May 17, 2014 at 16:37
  • Also add: else product = new Product();
    – jabbo
    Commented May 17, 2014 at 16:40
  • Thanks jabbo! I made the adjustments to my code (see the updates above). I am monitoring the code in the debug log and the url is getting correctly pulled in, but the link doesn't show up in my email because the product name is not coming thru. Here is what it shows in the debug log: Request: <a href="http://cs11.salesforce.com/a03Z0000008JykrIAC">WISH-000000001</a><br /> Inventory: <a href="https://cs11.salesforce.com/01tZ0000001Gt6KIAS"></a> The inventory product name is not coming thru. I can query by id and get the name. Any ideas why is not coming thru in the email?
    – Dman100
    Commented May 17, 2014 at 22:59

You must log in to answer this question.

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