salesforceapexvisualforce

visualforce emailtemplate issue referencing a list in an Apex class


I suffer an error trying to implement a visualforce emailtemplate. The dev console gives me the following problem on the VF component: Unknown property 'String.Name' (line 0). I can't figure out how to resolve this. Consequently the email template doesnt work & gives me the error: <c:ProductOrderItemList can only contain components with an access level of global.

I aim to send an email from a Product Order (parent). In the email I want to include child records (product order items).

Apex class:

public  class ProductOrderTemplate
{
    public Id ProductorderID{get;set;}
    public List<Product_Order_Item__c> getProductorderItems()
    {
        List<Product_Order_Item__c> toi;
        toi = [SELECT Product_Type__r.Name, Quantity__c FROM Product_Order_Item__c WHERE Product_Order__c =: ProductorderID];
        return toi;
    }
}

The visualforce component:

<apex:component controller="ProductOrderTemplate" access="global">
    <apex:attribute name="ProductOrdId" type="Id" description="Id of the Product order" assignTo="{!ProductorderID}"/>
    <table border = "2" cellspacing = "5">
        <tr>
            <td>Name</td>
            <td>Quantity</td>               
        </tr>
        <apex:repeat value="{!ProductorderID}" var="toi">
        <tr>
            <td>{!toi.Name}</td>
            <td>{!toi.Quantity}</td>             
        </tr>
        </apex:repeat>       
    </table>
</apex:component>

And the email:

<messaging:emailTemplate subject=“Product Order” recipientType="User" relatedToType=“Productorder”>
    <messaging:htmlEmailBody >
    Hi,<br/>
    Below is the list of ... for your Product order {!relatedTo.Name}.<br/><br/>
    <c:ProductOrderItemList ProductOrderId="{!relatedTo.Id}" /><br/><br/>
    <b>Regards,</b><br/>
    {!recipient.FirstName}
    </messaging:htmlEmailBody>
</messaging:emailTemplate>

Any help much appreciated! Quite stuck on this. I'm new to visualforce and apex. ​​​​​​​


Solution

  • You might need just a VF email template without component and apex class. Go to Product_Order_Item__c object, find Product_Order__c field definition. Write down the "Child Relationship Name".

    Let's say it'll be "Line_Items". You need to add "__r" to the end (why?) and then you can do something like that:

    <messaging:emailTemplate subject="Product Order" recipientType="User" relatedToType="Productorder">
        <messaging:htmlEmailBody >
        
        <p>here are your line items</p>
        <table>
            <apex:repeat value="{!relatedTo.Line_Items__r}" var="item">
                <tr>
                    <td>{!item.Name}</td>
                    <td>{!item.Quantity}</td>             
                </tr>
            </apex:repeat>
        </table>
        </messaging:htmlEmailBody>
    </messaging:emailTemplate>
    

    If you still think you want Apex and component (maybe you want to filter some records out, maybe you want to have them sorted or have a reusable piece of markup to use in multiple emails)...

    ... the error you're getting is because ProductorderID is a single String (well, Id) variable. But you've used it in a repeat that expects a list/array. A reference to <apex:repeat value="{!ProductorderItems}" var="toi"> should call your getProductorderItems() and work better.