The sample code for embedding a lightning flow component in a visualforce page includes a function that appears to be for handling the output variables from the flow component.

var statusChange = function (event) {
               if(event.getParam("status") === "FINISHED") {
                  var outputVariables = event.getParam("outputVariables");
                  var outputVar;
                  for(outputVar in outputVariables) {
                     if(outputVar.name === "redirect") {
                        // Do something
                     }
                  }
               }
            };

However, I am unable to get this to function. I've added some simple logging within the function and am not seeing anything logged, indicating that the function is not being called at all.

var statusChange = function (event) {
             console.log("fxn fired");
               if(event.getParam("status") === "FINISHED") {
                   console.log("flow finished");
                  var outputVariables = event.getParam("outputVariables");
                  var outputVar;
                  for(outputVar in outputVariables) {
                     if(outputVar.name === "vaOutput") {
                        console.log("vaOutput found");
                        window.parent.location = '/' + event.getParams().vaOutput;
                     }
                  }
               }
            };

I'm guessing perhaps I need to add some (stuff) to my lightning app itself, as the sample in the documentation is just these 3 lines.

<aura:application access="global" extends="ltng:outApp" >
    <aura:dependency resource="lightning:flow"/>
</aura:application>

Is there something missing from the code that would allow this to work? If it does, it would be most awesome, as we could handle flow output variables in visualforce without need for a custom apex controller.

up vote 3 down vote accepted

Interesting, it does seem like the docs are missing something.

I believe the function they put there is intended to be a handler for the flow's onstatuschange event. See an example for putting an event handler in createComponent:

https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/js_cb_dynamic_cmp_async.htm

In the example code I'd focus on this line:

$Lightning.createComponent("lightning:flow", {}, ...

The second parameter is an empty object. This is where you'd normally pass in direct attributes of the component. So try replacing that {} with:

{"onstatuschange":statusChange}

I'm not sure if that'll actually work, or if you need to do some sort of binding to a Lightning controller function, but if it fails you're likely to at least get an error message to start you off!

--- EDITED to add insight from comments

Here's the other problem with Salesforce's code sample.

JS for (k in obj) syntax returns the key not the value. So of course you're getting 0! That's the array index. What you really need to do is:

for (key in outputVariables){
    if outputVariables[key].name == 'vaOutput' {
        // make your decisions here
    }
}

Alternate array iteration syntax instead of for .. in:

outputVariables.forEach( function(outputVar){
    if outputVar.name == 'vaOutput' {
        // make your decisions here
    }
} );

If you have a LOT of output variables it might make sense to rearrange them into a map before processing.

var outputMap = {};
outputVariables.forEach( function(outputVar){
    outputMap[outputVar.name] = outputMap.[outputVar.value];
} );

Then instead of using an if statement to find each output, you can just access them from the map.

  • you nailed it - that got the logs firing. now i need to figure out why console.log(outputVar.name) = undefined. Its strange b/c i'm logging outputVariables and its an array of objects, and the object has a name property. Will do some more reading / debugging to see what i can figure out on that front, but the final value from the flow variable is coming through, so w/ some better JS chops this seems feasible! – gorav Dec 2 '17 at 21:19
  • Glad to hear that helped. I wasn't even sure if the event object would end up passed as the first parameter, since inside Lightning it's usually the second parameter. I wonder if the object it returns is a bit cryptic due to Locker Service? Maybe try logging JSON.stringify(outputVariables) to see what you're getting back? – Charles T Dec 2 '17 at 22:37
  • outputVariables logs as : [{"dataType":"STRING","name":"vaOutput","isCollection":false,"flowName":"User_EditFields","value":"12345","objectType":null}] but the loop variable logs as outputVar = 0 therefore outputVar.name = undefined perhaps something aint working right in the loop...will keep poking! – gorav Dec 3 '17 at 0:00
  • 1
    OK what was Salesforce smoking with that code??? I totally forgot this until your latest response, but JS for (k in obj) syntax returns the key not the value. So of course you're getting 0! That's the array index. What you really need to do is for (key in outputVariables) and then compare if outputVariables[key].name == 'vaOutput'. – Charles T Dec 3 '17 at 5:05
  • 1
    Cool! Glad it works. Yeah I think there are other best practices for redirection but that's out of scope of this question. – Charles T Dec 3 '17 at 17:39

Your Answer

 
discard

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.