[SalesForce] Handling output variables from a lightning flow component embedded in visualforce page

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.

Best Answer

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.

Related Topic