5

I have a Visualforce page that is referencing a controller extension, but I am getting an Unknown Constructor error, which appears to indicate that the controller doesn't exist (but it does). I have been troubleshooting my code, but can't figure out what's wrong with my code.

Here is my Visualforce page code:

<apex:page standardController="Task" extensions="LSHfTaskFlowControllerExtension" showHeader="false" sidebar="false">
<flow:interview name="LogSalesHistoryFromTask" finishLocation="{!SalesHistoryID}" >
   <apex:param name="TaskID" value="{!Task.Id}" />
 </flow:interview>

Here is the error:

Error Message:

Here is the Controller Extension Code:

public class LSHfTaskFlowControllerExtension {
public Flow.Interview.LogSalesHistoryFromTask historyFlow { get; set; }
public String getSalesHistoryID() {
if (historyFlow==null) return '';
else return historyFlow.SalesHistoryID;
}
public PageReference getOID(){
PageReference page = new PageReference('/apex/LogSalesHistoryFromTask?id=' + getSalesHistoryID() + '&addTo=' + getSalesHistoryID() + '&retURL=%2F006%2Fe&sfdc.override=1');
page.setRedirect(true);
return page;
}
}

Can anyone tell me what I have done wrong? Thanks!

I think I have added a constructor as highfive indicated, but I am still getting the error. Here is my revised controller

public class LSHfTaskFlowControllerExtension {
private final Task task;
public LSHfTaskFlowControllerExtension(){}
public Flow.Interview.LogSalesHistoryFromTask historyFlow { get; set; }
public String getSalesHistoryID() {
if (historyFlow==null) return '';
else return historyFlow.SalesHistoryID;
}
public PageReference getOID(){
PageReference page = new PageReference('/apex/LogSalesHistoryFromTask?id=' + getSalesHistoryID() + '&addTo=' + getSalesHistoryID() + '&retURL=%2F006%2Fe&sfdc.override=1');
page.setRedirect(true);
return page;
}
}

I am very new to coding (this is my first Apex Class). The class/extension doesn't seem right to me, but I don't know what I am doing wrong. I think I am close, but am missing something in how everything works together.

Essentially I am trying to embed a flow in a visualforce page, and configure the finish location attribute to route the user to the newly created record. The flow is started from a button on the standard task object, and during the flow a Sales History (custom object) record is created (newly created Record ID is stored as a variable in the flow {!SalesHistoryID}). The flow directs the user to another screen confirming the record was created. I want the user to be taken to the newly created Sales History record when the user clicks the flows finish button.

I hope this makes sense. Thanks!

Okay I added the standard controller (versus custom controller) constructor to my class. Here is code

public class LSHfTaskFlowControllerExtension {
private final Task task;
public LSHfTaskFlowControllerExtension(ApexPages.StandardController stdController){}
public Flow.Interview.LogSalesHistoryFromTask historyFlow { get; set; }
public String getSalesHistoryID() {
if (historyFlow==null) return '';
else return historyFlow.SalesHistoryID;
}
public PageReference getOID(){
PageReference page = new PageReference('/apex/LogSalesHistoryFromTask?id=' + getSalesHistoryID() + '&addTo=' + getSalesHistoryID() + '&retURL=%2F006%2Fe&sfdc.override=1');
page.setRedirect(true);
return page;
}
}

Now I am no longer getting the Unknown Constructor Error, the flow runs fine until the user clicks the finish button. Instead of being taken to the new Sales History record, I get an Invalid Page Redirection page error:

Invalid Page Redirection The page you attempted to access has been blocked due to a redirection to an outside website or an improperly coded link or button. Please contact your salesforce.com Administrator for assistance.

I know the flow is working properly, and the VF page works fine if I don't set the finish location, or if I set the finish location to be a VF page with a java script that closes the window, so I believe the problem is in my apex class.

It is my understanding that the VF page and apex class can leverage the variables in the flow as long as the flow is still running, and that there needs to be another screen after the record create so that the variable holding the newly created record id has a value. Is my controller/extension class getting the SalesHistoryID variable from the flow and passing it to the VF page properly? I've tried a few different things but keep getting the invalid page redirection error.

3
  • can you paste the LSHfTaskFlowControllerExtension class. I think you do have a user-defined constructor but when you use a standardController with extension you need to have a standardcontroller in your extension class. Can't jump into conclusion until you post the class
    – Rao
    Commented May 15, 2014 at 18:16
  • @rao Added my Controller Extension class. Essentially I am trying to embed a flow in a visualforce page, and configure the finish location attribute to route the user to the newly created record. In the flow a Sales History record is created (newly created Record ID is stored as a variable in the flow {!SalesHistoryID}). The flow directs the user to another screen confirming the record was created. I want the user to be taken to the new Sales History record when the user clicks the flows finish button. I am very new to code, so I think I am just overlooking something. Thanks!
    – Michele
    Commented May 15, 2014 at 18:36
  • highfive answered it for you :)
    – Rao
    Commented May 15, 2014 at 18:43

2 Answers 2

4

Check and make sure that in your controller extension you have a constructor like,

public LSHfTaskFlowControllerExtension{
  private final Task myTask;
  public LSHfTaskFlowControllerExtension(ApexPages.StandardController stdController) {
        this.myTask = (Task)stdController.getRecord();
        // Some code...
  }

  // Your code
}

This is a must when you are using a controller extension. Check here for more details to get an idea of why and benefits of having a controller extension. When you need get the benefit of a controller, there are two options.

Sometimes it's no need of having controller extension and we can work with just having a custom controller. In that case there are no mandatory constructors to be implemented. Here is the documentation.

0

After many attempts based on highfive's answer, I finally got everything to work.

Objective: Embed flow in Visualforce page, so that the flow is started from a custom button on the standard task object, the flow marks the originating task as completed then takes the user to a screen input form pre-populated with information from the originating task. The user then updates additional information and a new Sales History (custom object) record is created. User is then taken to a page confirming the Sales History was successfully logged, and the user is routed to the new Sales History record when they click the finish button.

Here is the final working code:

Visualforce page:

<apex:page standardController="Task" extensions="flowLSHfTaskContExt" showHeader="false" sidebar="false">
<flow:interview name="LogSalesHistoryFromTask" interview="{!historyFlow}" finishLocation="{!SalesHistoryPage}" >
   <apex:param name="TaskID" value="{!Task.Id}" />
 </flow:interview>

Apex Controller/Extension:

public class flowLSHfTaskContExt {
private final Task task;
public flowLSHfTaskContExt(ApexPages.StandardController stdController){}
public Flow.Interview.LogSalesHistoryFromTask historyFlow { get; set; }
public String getSalesHistoryID() {
if (historyFlow==null) return '';
else return historyFlow.SalesHistoryID;
}
public PageReference getSalesHistoryPage(){
    return new PageReference('/' + getSalesHistoryID());
    }
}

Thanks for the help highfive.... now I just need to create the test class! :)

You must log in to answer this question.

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