You need to sign in to do that
Don't have an account?
Using a query and update in a Page Reference
Modifying some existing code that updates a record and then redirects to a new page. I need to change it so that it runs a query to identify the correct record to update, and then updates the record.
How can I query the object to find the next suitable record to update and still create the PageReference I need to move forward?
public PageReference saveAttendee(){ List<CnP_PaaS_EVT__Event_attendee_session__c> attendee = [SELECT Id, Name, DTCI_Agreement_Active__c, CnP_PaaS_EVT__First_name__c, CnP_PaaS_EVT__Last_name__c, DTCI_Ticket_Level__c, CnP_PaaS_EVT__EventId__r.CnP_PaaS_EVT__category__r.name FROM CnP_PaaS_EVT__Event_attendee_session__c WHERE CnP_PaaS_EVT__Registrant_session_Id__c =:registrantId AND DTCI_Ticket_Level__c =: ticketLevel AND DTCI_Attendee_Info_Assigned__c = FALSE ORDER BY DTCI_Ticket_Order__c LIMIT 1 ]; attendeeId = attendee.Id; attendeeFirstName = attendee.CnP_PaaS_EVT__First_name__c; attendeeLastName = attendee.CnP_PaaS_EVT__Last_name__c; mailingCity = attendee.DTCI_Mailing_City__c; mailingCountry = attendee.DTCI_Mailing_Country__c; mailingCounty = attendee.DTCI_Mailing_County__c; mailingState = attendee.DTCI_Mailing_State__c; mailingStreet = attendee.DTCI_Mailing_Street__c; mailingZip = attendee.DTCI_Mailing_ZIP_Postal_Code__c; update attendee; PageReference sendToReleaseForm = new PageReference('/apex/DTCI_Release_Form_Page_AB' + '?attendeePageId=' + attendee.id + '®istrantPageId=' + registrantId + '&eventPageId=' + eventId + '&releasePageType=' + attendee.DTCI_Release_Type__c); sendToReleaseForm.setRedirect(true); return sendToReleaseForm; }
How can I query the object to find the next suitable record to update and still create the PageReference I need to move forward?
All Answers
CnP_PaaS_EVT__Registrant_session_Id__c =:registrantId (registrantId is provided by a variable in the custom controller that collects a URL parameter)
DTCI_Ticket_Level__c =: ticketLevel (ticketLevel is provided by a variable in the custom controller )
and DTCI_Attendee_Info_Assigned__c = FALSE
The attendee object may have several records that meet those qualifications- that's why I added LIMIT 1 to the query
Also, if you think it helps with readability, you can set url parameters as follows...
The records already exist- someone purchases 2 adult tickets, 2 youth tickets- this creates 4 attendee records, mostly unpopulated. Attendees fill out the form when they arrive. The attendee chooses their party, and then which ticket to check-in on. I want the attendees to see both adult tickets and youth tickets as what tickets are unassigned, but I don't want to assign a specific ticket until the attendee has filled out the form.
The form looks like this:
I'm not sure how I would need to change the form so that it doesn't display existing info (b/c would no longer be a defined record- it couldn't). I'm guessing I would remove the value on the input fields and let the param define what field values would be applied for the update?
I hope that clarifies enough.
Here is a sample of the other code from my extension (I didn't include all the fields- but they are similarly set up):
I don't need any fields populated prior to the guest checking in (CnP_PaaS_EVT__Registrant_session_Id__c and DTCI_Ticket_Level__c are populated when the tickets are purchased) - so I collect URL parameters needed for the query.
"Attempt to de-reference a null object
Error is in expression '{!saveAttendee}' in component <apex:commandButton> in page dtci_attendee_info_page_ab: Class.DTCI_Attendee_AB_Ctrl.saveAttendee: line 110, column 1" (this line references the ApexPages.addMessage)
Here's what I have now, I think the only major change I made to what you suggested was changing attendeeListFor to nextAvailableTicket(), and I placed nextAvailableTicket before saveAttendee():
I've tested the nextAvailableTicket method, and it is returning results- I called it in the page with javascript to make sure.
I've added some if conditions to set a value for releaseType, which is a value that needs to be updated if nextAvailableTcket returns a result or remains the record's current value if it is not. It also needs to be passed as a param in sendToReleaseForm.
I don't really think that is what is causing the error. What can I do next?
If you can't get it - we will probably need to see that class and method.
1. If the attendeeId is not blank, you will never enter the IF block
2. if your nextAvailableTicket() method returns an empty list, you will not enter the FOR-loop.
When your attendee variable remains null, you will not be able to use "attendee.Id", which is in your addMessage() call, Line 38 above.
It's not clear why a page message would be added there. The IF statement immediately following that page message call checks to see whether an attendee is found, in order to avoid null pointer errors in lines 47-68 above.
Now I'm getting a
"SObject row was retrieved via SOQL without querying the requested field: CnP_PaaS_EVT__Event_attendee_session__c.DTCI_Mailing_City__c
Error is in expression '{!saveAttendee}' in component <apex:commandButton> in page dtci_attendee_info_page_ab:
Currently you are requesting only Id, Name, DTCI_Agreement_Active__c, CnP_PaaS_EVT__First_name__c, CnP_PaaS_EVT__Last_name__c, DTCI_Ticket_Level__c, and CnP_PaaS_EVT__EventId__r.CnP_PaaS_EVT__category__r.name. So you'll have to add more fields to the query, particularly all of those referenced in lines 43 through 61.
Keep asking questions. I'm happy to help.
I have an "if" that determines whether or not the page loads with an attendeeId parameter or not, and if so sets attendee = (CnP_PaaS_EVT__Event_attendee_session__c) controller.getRecord();
the next reference to "attendee" is in saveAttendee(), where attendee is set to the first result of the nextAvailableTicket query- presumably replacing the values that would have been collected from the form.
the Form fields read like this: The original version of this app ran the query for the correct record and the relevant fields before loading the form page, and would populate the form with the values from that. I've commented this code out- because I don't want the record assigned until the "saveAttendee()" is activated. the correct record is called function called by the page 'before' the form page that uses the same extension class.
This new version needs to assign the record when the form page loads if attendeeId is a URL parameter, otherwise it should not assign a record until saveAttendee() is called. The problem seems to come when I set attendee = firstResult, I replace the values from the form with the values from the record.
I tried changing each field from attendeeFirstName = attendee.CnP_PaaS_EVT__First_name__c to attendee.CnP_PaaS_EVT__First_name__c = attendeeFirstName; this caused errors for all of the 'checkbox' fields that were declared Boolean in the class. But even when I commented those out and could save the extension class- the values on the record remained the same.
Apparently writing it like a SQL query isn't an option, e.g. Update attendee set attendee.CnP_PaaS_EVT__First_name__c = attendeeFirstName...
You mention, "This new version needs to assign the record when the form page loads if attendeeId is a URL parameter, otherwise it should not assign a record until saveAttendee() is called." This sounds like something that I would typically do in a constructor, or in an initialize() method called from a constructor, where the record to be saved/updated is either located from the database or newly instantiated when the page loads.
So if the url parameter is provided, the constructor in the page's extension would locate the existing record and pre-populate the form fields. If no url parameter is provided, then the save method might search for a matching record based on some information provided by the form, and if a match is found then update it with newly entered information, else create a new record from the information entered into the form.
1. Select from available tickets in party -if ticket type is Youth or Child, skip to Attendee Info
2. Minor Question page for Adults (13 and up) - . The page offers two buttons, one for checking in on behalf of a minor, and the other to check in as an adult.The extension class includes Page References MinorNo() and a MinorYes() for this page
3. A page listing checked-in Guests, linking to the pre-filled Attendee Info page with AttendeeId, so users/staff can modify incorrect information.
The original application pre-selected the attendee record and had an Id prior to arriving at the Attendee Info page. We have 4 check-in kiosks, so if more than one person in the same party and with the same ticket type checks in on a different kiosk simultaneously, the slower check-in overwrites the first one.
Here's a only slightly summarized breakdown of the entire extension class in its current state.
Thank you so much for your time- this app has been hounding me for months, really upwards of a year.
The variables are declared, and 'got' and 'set' , but I needed to select the record I was updating in one of the methods. When I created the List for the query results, I needed to include all my fields in order to update them later, but the List reset the values of the variables from the ones I had collected from the form to the empty ones in the database.
I changed
(nextAvailableTicket is a List method that calls the record to use)
and instead of setting attendee = firstResult, I set attendee.id=firstResult.Id, so I wasn't writing over all my existing values!
Of course now it seems obvious.
HURRAY!!!!!!
(my head hurts)