You need to sign in to do that
Don't have an account?
neckr
Save Function not Updating Child Objects but saves fine
Hi, I am trying to display and update fields for an my License_Verification__c Object
with a lookup with Contacts. I want to update and save in one shot, however my
contact fields are not being updated on Save and not sure what I am missing, please help.
public with sharing class ConAcctVerificationInfoControllerExt { private ApexPages.StandardController std; // Associated Licenses public List<License_Verification__c> licenses; // License Agency Contact Contact LicenseAgencyContact; public ConAcctVerificationInfoControllerExt(ApexPages.StandardController stdCtrl) { std=stdCtrl; } public Account getAccount() { return (Account) std.getRecord(); } //----------------------------LICENSES METHOD---------------------------------------> public List<License_Verification__c> getlicenses() { if ( (null!=getAccount().id) && (licenses == null) ) { licenses=[SELECT Id, Account__r.ID, Account__c, LV_Agency_Contact__r.ID, LV_Agency_Contact__r.Company_Name__c,LV_Agency_Contact__r.Email, LV_Agency_Contact__r.Phone, LV_Agency_Contact__r.LastName,LV_Agency_Contact__r.FirstName, LV_Agency_Contact__r.Fax, LV_License_Type__c, LV_License_Number__c,LV_License_Expiration_Date__c FROM License_Verification__c WHERE Account__c = : getAccount().ID ORDER BY CreatedDate]; } return licenses; } public PageReference save() { Boolean result=true; PageReference pr=Page.TestParentChild; if (null!=getAccount().id) { result=updateContacts(); } else { pr.setRedirect(true); } if (result) { // call standard controller save, but don't capture the return value which will redirect to view page update Principalcontact; update IDV; update licenses; // ONLY FIELDS ON PARENT OBJECT ARE BEING UPDATED ON SAVE std.save(); ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.INFO, 'Changes saved')); } pr.getParameters().put('id', getAccount().id); return pr; }
<apex:page standardController="Account" extensions="ConAcctVerificationInfoControllerExt" title="Test Verification Info" > <apex:pageMessages /> <apex:form > <apex:pageBlock mode="mainDetail"> <apex:pageBlockButtons location="top"> <apex:commandButton action="{!cancel}" value="Exit" /> <apex:commandButton action="{!save}" value="Save" /> </apex:pageBlockButtons> <apex:repeat value="{!licenses}" var="license" > <apex:pageBlockSection columns="2" title="License {!license.LV_License_Type__c}:{!license.LV_License_Number__c} Verification" collapsible="true"> <!--<apex:repeat value="{!$ObjectType.License_Verification__c.FieldSets.LV_Input_Info}" var="field"> <apex:inputField value="{!license[field]}" /> </apex:repeat>--> <apex:inputfield value="{!license.LV_Agency_Contact__r.ID}" /> <apex:inputfield value="{!license.Account__r.ID}" /> <apex:inputfield value="{!license.LV_License_Type__c}"/> <apex:inputField value="{!license.LV_Agency_Contact__r.FirstName}" /> <apex:inputfield value="{!license.LV_License_Number__c}"/> <apex:inputField value="{!license.LV_Agency_Contact__r.LastName}" /> <apex:inputfield value="{!license.LV_License_Expiration_Date__c}"/> <apex:inputField value="{!license.LV_Agency_Contact__r.Email}" /> <apex:inputfield value="{!license.LV_Agency_Contact__r.Company_Name__c}"/> <apex:inputField value="{!license.LV_Agency_Contact__r.Phone}" /> <div style="text-align:center"> <apex:commandButton action="{!save}" value="Save" /> <!--<apex:commandButton action="{!AddNewLicense}" value="Add New" /> --> </div> </apex:pageBlockSection> </apex:repeat>
My bad...
public List<Contact> LicenseAgencyContact;
LicenseAgencyContact = new List<Contact>(); // initialise if not already done so
for (License_Verification__c lic : licenses) {
LicenseAgencyContact.add( lic.LV_Agency_Contact__r );
}
All Answers
So if I understand correctly, your licenses get updated, but not the values that have been applied to the related LV agency contact?
I'm pretty sure you can't do this - I'm sure I've read that Apex won't traverse the object graph, probably something to do with the fact that your update would be affecting sobjects of multiple different types. I'll try to find the doc that I read this in.
This is what the Apex developer's guide has to say. Its related to upsert, but specifically talks about updates and there's a similar entry for the insert method:
--- snip ---
--- snip ---
You'll need to create a variable in your class to store the LV_Agency_Contact__c and do a seperate update on it.
Ok. Thanks for the help.
In terms of your suggestion to create a new class variable, I created
public List<Contact> LicenseAgencyContact;
However not sure how I would assign the query list results of <License_Verification__c> to <Contact> type within my class.
Thinking along these lines, but didn't fly.
LicenseAgencyContact = licenses.LV_Agency_Contact__r;
Do I need to run a seperate query to populate the <Contact> List. I was initially going in this direction and got stumped with mapping the two lists together, so looked for what I thought would be a simplier solution. A code example would help me understand your suggestion a bit better.
Thanks,
Ricky
for (License_Verification__c lic : licenses) {
for (Contact con : lic.LV_Agency_Contact__r) {
LicenseAgencyContact = con;
}
}
might work, and there is only one licence and contact.
There is a one to one relationship between license and contact however there can be multiple liceneses.
I tried putting the code within the public List<License_Verification__c> getlicenses() method and I receieve this error.
Illegal assignment from SOBJECT:Contact to LIST<Contact>
It appears that this line lic.LV_Agency_Contact__r is not reading as a Contact Object.
Is there something else I am missing?
Ah I think its down to List of objects vs. object. Would this work? Changing the variable to a single object.
LicenseAgencyContact = licenses.LV_Agency_Contact__r; << doesn't work since licences is a List rather than a single License_Verification__c object.
try this? Make a variable of type Contact.
public Contact LicenseAgencyContact;
for (License_Verification__c lic : licenses) {
LicenseAgencyContact = lic.LV_Agency_Contact__r;
}
The syntax your provided works however since LicenseAgencyContact is no longer a list it wouldn't store and save all contacts and I tested it with two Liscneses and two contacts and it only saves the changes to the 2nd Contact.
So I guess I would have to go back to your fist code suggestion and iterate over the licenses and assign them to LicenseAgencyContact. Not sure where to begin with the syntax, can you provide an example or do you see the solution differently?
I'm thinking someting like this?
public List<Contact> LicenseAgencyContact;
//int i=0;
for (License_Verification__c lic : licenses[i]) { // add int i =0; i++;
for (Contact con : lic.LV_Agency_Contact__r) {
LicenseAgencyContact = con;
}
}
OK, if we go back to a List of Contacts then I think
public List<Contact> LicenseAgencyContact;
LicenseAgencyContact = new List<Contact>(); // initialise if not already done so
for (License_Verification__c lic : licenses) {
for (Contact con : lic.LV_Agency_Contact__r) {
LicenseAgencyContact.add(con);
}
}
Thanks for the syntax help for the list. I get this error for this line for (Contact con : lic.LV_Agency_Contact__r)
Error: Loop must iterate over a collection type: SOBJECT:Contact
Looks like same issue as before not reading licenses.LV_Agency_Contact__r as a Contact Object. Any ideas?
My bad...
public List<Contact> LicenseAgencyContact;
LicenseAgencyContact = new List<Contact>(); // initialise if not already done so
for (License_Verification__c lic : licenses) {
LicenseAgencyContact.add( lic.LV_Agency_Contact__r );
}
Perfection! Thanks for your help, much appreciated!
I have a delete License Method where I am trying to delete the License record and associated Contact record in one shot. It has no problem deleting the License record but gives me an error when trying to delete the Contact record associated.
System.ListException: Missing id at index: 0
Is there something I am missing when capturing the contact Id for the delete function? I am a bit stuck on what I can possibly do next, pleas help. Here is my method:
Does this line actually work?
Assuming you have your list of licenses variable still populated, I would loop through it and pull out the licence matching the licence number; it would have all the object relationships and values in it so you should be able to ge the right contact or contact id.