3

I have an embedded visualforce page which calls a controller method on load.

<apex:page name="calloutPage" standardController="Case" extensions="WsCallout" action="{!getSomething}" standardStylesheets="false" >

Is there a way to call a javascript function after the controller method finishes execution, something similar to an oncomplete on a commandbutton? I am looking to reload the case page after the inline visualforce page's action call is complete.

function caseload(){
   window.top.location='/{!Case.id}'; return false;
 }

UPDATE: The idea is to do a callout to an external web service on page load and based on the values coming in, update some case fields. The case fields are getting updated as expected. However, the UI still shows the old values. If the page is refreshed a second time the UI shows the new values.

4 Answers 4

1

Note: Window.top.location wont work in lightning so you should start curbing that habit now.

Original Answer

You can simply move the fields to be internal to the VF page and display the updated data after your callout is completed. This will avoid the need for a page refresh which is both lightning compatible and avoids the infinite refresh loop discussed in the comments of this post.

Alternative Method:

Note: If you go down this path you can find a workable solution; however, for reasons discussed in the comments this is not the most straightforward or ideal solution.

Take your action out of the action attribute and move it into an action function on the page:

<apex:actionFunction name="jsName" action={!getsomething}/>

Then, put a script into the page to call it:

<script>
function reload() {
jsName();
}

reload();
</script>

Instead of using JS to redirect, use the controller. Action methods are allowed to return a pageReference that will redirect the user upon completion. Than, use login in your controller to determine if the update actually needs to be called (check the fields on your case to see if the data is correct). If it doesn't need to be called, return a null pageReference:

public pageReference getSomething () {
if (Case.field != value) {
// Do your crazy stuff
return new PageReference('/' + Case.Id);
} else {
return null;
}
}
0
1

It sounds like you may want to use a Continuation. I have not had a chance to use this feature yet, but based on the documentation, you will define a method in your controller like:

public Object caseUpdateCallback()
{
    return null;
}

And in your action method, create a Continuation object that calls the method:

public Object myAction()
{
    HttpRequest req = new HttpRequest();
    req.setMethod('GET');
    req.setEndpoint('requestsite');
    Continuation cont = new Continuation(60);
    cont.continuationMethod = 'caseUpdateCallback';
    cont.state = cont.addHTTPRequest(req);

    return cont;
}

This will cause the page to load and start the request, then post back once the request finishes with the updated data.

Some code taken from this blog post.

2
  • Thanks for your help. The continuation seems to be something for async callouts. In my case the callout is successful and the new values are saved in the case fields. If I run a soql query after page load it gives me the updated values. However, the UI still shows the old value since (my assumption) the inline visualforce is processed after the parent is rendered. So, some kind of rerender or refresh on the top page will put the new values on the UI. Something like an oncomplete would work perfectly but since the action is on page, I am unable to do an oncomplete.
    – Vick
    Commented Mar 17, 2017 at 20:30
  • @Vick Ah, I see what your issue is then. Calling the standard controller's reset method after the callout might work, or populating a copy of the record in your extension and then calling SOQL again after the callout to give it the updated values before the page loads. Commented Mar 17, 2017 at 21:00
0

Use action function oncomplete attribute. In vf page call action function on load of that page. So action function will call controller method on load of page. Then oncomplete attribute will call your JavaScript method after execution of controller method.

I am adding a code snippet which is perfectly working for me.

VF page

<apex:page controller="test1" >
<script>
 function callJavascript(){
    callActionFunction();    
 }

 function onloadcomp(){
    console.log('After load called');    
 }
 </script>

 <apex:form>

    <apex:actionFunction action="{!controllermethod}" oncomplete="onloadcomp()" reRender="" name="callActionFunction"/>
</apex:form>
<body onload="callJavascript()"> 
</body>

Controller

public class test1 {

   public void controllermethod(){
      system.debug('Controller Called');
  }
}

Let me know is this was helpful.

0
0

Here is how I would quickly solve it:

  1. Create a page to do the action:

    <apex:page name="calloutPage" standardController="Case" extensions="WsCallout" action="{!getSomething}"/>
    
  2. Create the final page without action parameter using same controller and extension

    <apex:page name="afterCalloutPage" standardController="Case" extensions="WsCallout"/>
    
  3. In the WsCallout controller do this

    public page reference getSomething(){
        //..Do callout
        PageReference pr = Page.afterCalloutPage;
        pr.setRedirect(false);
        return pr;
    }
    

This give you finite control on how things happen and where you get taken. You can even goto error pages if callout fails etc.

I am sure there may be other ways but this to me would be the easiest and least fragile

0

You must log in to answer this question.

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