0

I have three Objects, Package_Item__c ,Product__c, Package__c.

Package_Item__c fields - Name, Quantity__c, Product__c(lookup to Product__c), Package__c(Lookup to Package__c)

Product__c fields - Name

Package__c fields - Name

I have a VF Datatable, that takes input of the Package_Item__c Quantity fields - as follows

<apex:page controller="CustomCnt">
<apex:form>
<apex:inputField label="Name" value="{!pkg.Name}"/>
<apex:dataTable value="{!packageItems}" var="pkg1">
            <apex:column>
                <apex:inputField value="{!pkg1.Quantity__c}"/>
            </apex:column>

            <apex:column>
                
                    <apex:outputText value="{!pkg1.Product__r.Name}"/>
                
            </apex:column>
        </apex:dataTable>
<apex:commandButton action="{!saveAll}" value="Save"/>
                <apex:commandButton value="Cancel"/>
</apex:form>

My Requirements - The values entered in the Datatable, should be saved as a new Package_Item__c record with the Product__c Lookup field set to the one displayed on the outputtext, upon clicking the 'Save' button.

For eg - If The Quantity__c value Entered as '2', corresponding to the outputtext 'Apples' , the Package_Item__c record saved should be Name = Apples, Quantity = 2, Package = Value of Inputfield labelled 'Name'

Here is what I have tried

public with sharing class CustomCnt
{
public Package_Item__c[] packageItems {get; set;}
public Package__c pkg {get; set;}

public CustomCnt()
{
pkg = new Package__c();
}
public void saveAll()
    {
        
        
        for(Package_Item__c p : packageItems)
        {
            pkgitem1 = new Package_Item__c(Name = p.Product__r.Name, Quantity__c = p.Quantity__c, Package__c = pkg.Package__r.Name);
            insert pkgitem1;
        }
        
        
    }

I am getting an error as - "Variable does not exist: Package__r", on the above code.

1 Answer 1

1

As far as I can tell, pkg.Package__r.Name should be pkg.Id.

A lookup field, in Apex, is always set by Id, not by name. Further, your code is trying to say that Package__c.Package__r.Name, which suggests that the package has a parent package, which I'm pretty sure that's not what you're trying to do.

pkgitem1 = new Package_Item__c(Name = p.Product__r.Name, Quantity__c = p.Quantity__c, Package__c = pkg.Id);

Also, you should not be inserting records in a loop. Add all the records to a list, then insert them all at once.

Package_Item__c[] items = new Package_Item__c[0];
for(Package_Item__c p : packageItems) {
    items.add(new Package_Item__c(Name = p.Product__r.Name, Quantity__c = p.Quantity__c, Package__c = pkg.Id));
}
insert items;

Finally, you can insert the reords directly from packageItems, you don't need the interim step of copying the records.

for(Package_Item__c p : packageItems) {
    p.Name = p.Product__r.Name;
    p.Package__c = pkg.Id;
}
insert packageItems;

There's a few other bugs here, too, but I presume it's simply missing code from this question (e.g. you never insert pkg, so it's not a record). You may have more work to do.

2
  • Thanks this worked. Yes actually I did insert pkg, just didnt post the code here. Also could you explain how is the third solution working? As I see that you're setting the fields to the loop variable, but inserting packageItems.
    – An Amateur
    Dec 14, 2020 at 16:35
  • @AnAmateur I suggest you read this and this, as they go in to more detail about this behavior, but basically, the loop variable p is a reference/alias to packageItems[i] (where i would be the current index of the loop), so we can modify the items in the list directly instead of creating a copy. This is often more efficient and what we intend to do.
    – sfdcfox
    Dec 14, 2020 at 17:08

You must log in to answer this question.

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