+ Start a Discussion
kprkpr 

Urgent prod issue. Please help...Page getting posted without id

I have overridden the 'Add Product' functionality in Opportunity and for this I have a visualforce page (using a controller extension) which has a few command buttons that invoke action methods to do the searching of products.

 

The issue is, 'sometimes' when I click on one of the action methods, the constructor of the extension is run and the id in the url is missing and so the query I have in the constructor returns no rows.

 

opportunityId = ApexPages.currentPage().getParameters().get('id');
thisOpp=[select id,Pricebook2Id,accountId,ownerId,Name,StageName,Approval_Status__c,Account.Channel__c,Account.BusinessUnit__c,Account.Cust_group__c,Account.Local_Currency__c,Account.Tier__c,Account.Pricebook_Id__c,Account.Slotting_SKUs__c,Meeting_Date__c,CloseDate,Probability,Type,Description,NextStep,CampaignId from Opportunity where id =:opportunityId];

 

This doesn't happen always---only sometimes

 

This also occurs sometimes when navigating from one page to another, whether the pages are using the same controller extension or a different one.

 

I am using the following syntax to navigate from one page to another:

 

Pagereference p = new Pagereference ('/apex/SelectOpportunityProducts?id='+opportunityId);

 

Can anyone help me out please?I have an  urgent production issue and I haven't seen this issue earlier while testing in sandbox or production.

 

 

 

 

Message Edited by kpr on 01-13-2010 07:49 AM
Message Edited by kpr on 01-13-2010 08:48 AM
rtuttlertuttle

I assume you are using the standard controller as well since you said this is an extension controller?  If so you can call this code to get the actual SObject returned from the standard controller:

 

 Note: this code assumes you are have the variable "controller" in scope or stored in the class.

 

Opportunity opp = controller.getRecord();

 

Since this is in the constructor you should already have the standard controller class in the constructor.  If you need to retrieve the record later in the class I'd recommend storing it in the class.

 

 

Edit:  I also don't recommend you move your page that way as it contains a static mapping to the page.  If Salesforce ever changed the apex folder for visualforce pages your controller would break.  You should use the following syntax:

 

 

PageReference p = Page.SelectOpportunityProducts;

p.getParameters().put('id',this.controller.getId()); // assuming you stored the controller in the class, else replace with the id in a string

 

 

 

 

 

-Richard 

 

 

Message Edited by rtuttle on 01-13-2010 05:07 PM
Message Edited by rtuttle on 01-13-2010 05:07 PM
kprkpr

Richard,

 

I am indeed storing the Opportunity Object I retrieve via the query in the class.

 

But what happens is that the constructor is running again, which means the class is being initialized again and all the values I stored in the class, including the Opportunity object, are lost....why is the constructor called again when all I do is invoke an action function?....this is so strange, it happens sometimes, not always

rtuttlertuttle

Are you rerendering a specific section of the page?  If you don't it reloads the whole page, and I don't recall whether or not that initiates the constructor again.  I am guessing it does.  Try using the rerender tag and make it rerender a block of the page.

 

 

-Richard 

kprkpr

Thanks Richard,

 

That seems to solve the issue when the action method in the same page runs.(I say seems to solve as it this issue doesn't happen consistently and unless I do more testing I'd not be able to say definitely).

 

But the issue with the page navigation is still intact---when I click on a commandbutton on a page to navigate to another page, it 'sometimes'refreshes the same page w/o the id instead of going to the next page....(the controller extension of this page doesn't get the id and its constructor is run, hence the query in the constructor fails....but I see the id in the url of the page and when I refresh the page, the extension's constructor is run with the id and displays all the data)

rtuttlertuttle

Can you send an example of a function where you return the page to change to in the action?

 

 

-Richard 

kprkpr

public Pagereference addProduct(){ PageReference p = Page.SelectOpportunityProducts; p.getParameters().put('id',opportunityId); p.setRedirect(true); return p; }

I overwrote the OpportunityDetail page with a visualforce page. This page contains a button 'Add Product'

This button invokes the above function, to redirect to 'SelectOpportunityProducts.page'. But it fails sometimes and returns the error I mentioned in the earlier post.

 

rtuttlertuttle

Does anyone ever visit this page to create an opportunity?  If so the Opportunity SObject won't have an ID populated yet.  You'll need to call "controller.save()", then "controller.getID()" to get the active ID.

 

 

-Richard 

kprkpr

No, this is just the detail page...I overwrote the 'View' of the Opportunity. Opportunity creation is via standard salesforce page and once it's saved, this page is displayed as the detail page with the id already available.

 

This issue doesn't happen always. Only sometimes randomly.

rtuttlertuttle

Try getting the ID from the standard controller just to see if it helps (although technically your id field should never lose the value).

 

 

private ApexPages.StandardController controller;

public _classname_(ApexPages.StandardController controller) {

// your other code here

this.controller = controller;

}

 

public Pagereference addProduct(){

PageReference p = Page.SelectOpportunityProducts;

p.getParameters().put('id',this.controller.getId());

p.setRedirect(true);

return p;

}

 



-Richard

 

kprkpr

I actually tried this earlier:

 

private Opportunity thisOpp; private Opportunity oppFromVfPage; public OpportunityProductExtension8(ApexPages.StandardController controller) { System.debug('in constructor=---'); opportunityId = ApexPages.currentPage().getParameters().get('id'); oppFromVfPage = (Opportunity)controller.getRecord(); System.debug('opp 4m StandardController=='+oppFromVfPage); System.debug('opp id in constructor=='+opportunityId); }

 Both "oppFromVfPage" and "opportunityId" are null when this error occurs....in other words, there seems to be no use saving the controller record and try to use it the next time the constructor is called,...the class variables lose their values and the class is instantiated from scratch.

 

 

rtuttlertuttle

Right but the controller is passed to you in the constructor.  Its still a long shot cause it seems like you're having a different issue.  Worth a shot.  Otherwise I'd try to figure out why your constructor is getting recalled.  Might need a call to support to track what is making it lose the controller extension data.

 

 

 

-Richard 

kprkpr

I mean, the controller object obtained when the constructor is recalled, doesn't have the Opportunity details. It's an empty object.

 

I tried calling support and they don't seem to be of much help. One guy made me clean the browser cache and that was it. As the problem doesn't occur everytime,he assumed it got resolved and when I tried to reach tehm later, he was busy and I left a vm and he doesn't get back.

rtuttlertuttle

Yea, getting through the levels of support is sometimes tricky.  I've seen this issue in my org as well so I am familiar with the problem, but I've never found a definitive cause.  Are you using more than one apex:form on the page?  I've had problems with that in the past and have seen other issues around it.  One of which was data being lost in the viewstate and not returning to the controller.

 

 

-Richard 

kprkpr

Nope, I'm using a single form. I should try to reach them again I guess.

 

Thanks for the help Richard. I really appreciate it!

rtuttlertuttle

No problem, I hope you find the answer.  If you get it figured out post it back here for my own curiosity :)

 

 

-Richard 

kprkpr
Sure. I couldn't get hold of them today either. I'll let you know if I find an answer any way