function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Andee Weir 17Andee Weir 17 

Passing parameters from vfp to lightning component

Hi all,

I've read other postings about how to pass parameters from a visualforce page to a lightning component but cannot get it to work.  In my case I have created my own custom version of  a related list as a lightning component (All Financial Accounts in Third Party's Hierarchy) but want to add the functionality that if there are more than 6 items, the View All link at the bottom of the component opens up the same component in a new page with slightly different paramaters so that more columns & rows are shown (similar to normal related list functionality). 

Screenshot of custom component related list
I'm attempting to do this by navigating to a new visualforce page which uses lightning:isUrlAddressable but I get a 'Lightning out App error in callback function error' when it trys to display the lightning component.  This can be demonstrated in a cutdown version of the code :

LC1.cmp:
<aura:component implements='flexipage:availableForAllPageTypes, lightning:isUrlAddressable' access='global'> 
	<aura:attribute name="param1" type="String" default="AAA"/>    
    
    <p>{!v.param1}</p>
    <a href="javascript:void(0);" onclick="{!c.changeParam}">Change Parameter</a>    
    
</aura:component>

LC1Controller.js :
({
	changeParam : function(component, event, helper) {
		var urlEvent = $A.get("e.force:navigateToURL"); 
        urlEvent.setParams({ "url":"/apex/VfPage?param1=BBB" }); 
        urlEvent.fire();
	}
})
VfPage.vfp :
<apex:page >
    <apex:includeLightning />
    <script>
    $Lightning.use("c:LC1Container", function() {
            $Lightning.createComponent("c:LC1",
                                       {
                                           "param1" : "BBB" // Removing this still has the same error
                                       },
                                       "lightning",
                                       function(cmp) {
                                           console.log('Component created');
                                       });
        });
    </script>
    
    {!$CurrentPage.parameters.param1}
</apex:page>

LC1Container.app :
<aura:application access="GLOBAL" extends="ltng:outApp" >
    <aura:dependency resource="c:LC1"/>
</aura:application>
I then added LC1 to the top of the Account's Lightning Page | Related List tab.  The end result looks like :
Change param 1

When I click on Change Parameter I get :
Change param 2

​​​​​​​Any suggestions on how get this component to load successfully with the new value of the parameter?
​​​​​​​
Thanks for any help that can be offered.
Best Answer chosen by Andee Weir 17
Andee Weir 17Andee Weir 17
Thanks for the response Deepali. That link helped but it didn't solve my problem.  However I think I have got the bottom of it.  The full solution (for me) was :-

LC1.cmp
<aura:component implements='flexipage:availableForAllPageTypes,lightning:isUrlAddressable' access='global'> 
	// These are the 2 params I want to pass new values for when clicking the link
    <aura:attribute name="param1" type="String" default="AAA"/> 
    <aura:attribute name="param2" type="String" default="false"/>
    
    <p>{!v.param1}</p>
    <p>{!v.param2}</p>
    <p><a href="javascript:void(0);" onclick="{!c.changeParamVfp}">Change Parameter with VFP</a> </p>
    
</aura:component>
LC1Controller.js
({
	changeParamVfp : function(component, event, helper) {
		var urlEvent = $A.get("e.force:navigateToURL"); 
        // Pass new parameter values
        urlEvent.setParams({ "url":"/apex/VfPage?param1=DDD&param2=true" }); 
        urlEvent.fire();
	}

})

VfPage.vfp
<apex:page >
    <apex:includeLightning />
    <div id="lightning"/>
    
    <script> 
    	// Get the new values from the url and then create a new version of that component and pass it the params 
        var url = new URL(window.location.href);
		var param1 = url.searchParams.get("param1");
    	var param2 = url.searchParams.get("param2"); 
        $Lightning.use("c:LC1Container", function() {               
        $Lightning.createComponent("c:LC1", 
                                                  {'param1' : param1,
                                                   'param2' : param2},             
                                                  "lightning",
                                                  function(cmp) {             
                                                  });              
        });            
    
    </script>
</apex:page>

LC1Container.app
 
<aura:application access="GLOBAL" extends="ltng:outApp" >
    <aura:dependency resource="c:LC1"/>
</aura:application>

 

All Answers

Deepali KulshresthaDeepali Kulshrestha
Hi Andee, 

Create a simple event file and fire the event from the visualforce inside the callback and handle the event back in the lightning component file

I suggest you visit this link, it will help you

http://cloudyworlds.blogspot.com/2016/02/lightning-events-via-visualforce.html

I hope you find the above solution helpful. If it does, please mark as Best Answer to help others too.

Thanks and Regards,
Deepali Kulshrestha.
Andee Weir 17Andee Weir 17
Thanks for the response Deepali. That link helped but it didn't solve my problem.  However I think I have got the bottom of it.  The full solution (for me) was :-

LC1.cmp
<aura:component implements='flexipage:availableForAllPageTypes,lightning:isUrlAddressable' access='global'> 
	// These are the 2 params I want to pass new values for when clicking the link
    <aura:attribute name="param1" type="String" default="AAA"/> 
    <aura:attribute name="param2" type="String" default="false"/>
    
    <p>{!v.param1}</p>
    <p>{!v.param2}</p>
    <p><a href="javascript:void(0);" onclick="{!c.changeParamVfp}">Change Parameter with VFP</a> </p>
    
</aura:component>
LC1Controller.js
({
	changeParamVfp : function(component, event, helper) {
		var urlEvent = $A.get("e.force:navigateToURL"); 
        // Pass new parameter values
        urlEvent.setParams({ "url":"/apex/VfPage?param1=DDD&param2=true" }); 
        urlEvent.fire();
	}

})

VfPage.vfp
<apex:page >
    <apex:includeLightning />
    <div id="lightning"/>
    
    <script> 
    	// Get the new values from the url and then create a new version of that component and pass it the params 
        var url = new URL(window.location.href);
		var param1 = url.searchParams.get("param1");
    	var param2 = url.searchParams.get("param2"); 
        $Lightning.use("c:LC1Container", function() {               
        $Lightning.createComponent("c:LC1", 
                                                  {'param1' : param1,
                                                   'param2' : param2},             
                                                  "lightning",
                                                  function(cmp) {             
                                                  });              
        });            
    
    </script>
</apex:page>

LC1Container.app
 
<aura:application access="GLOBAL" extends="ltng:outApp" >
    <aura:dependency resource="c:LC1"/>
</aura:application>

 
This was selected as the best answer
Andee Weir 17Andee Weir 17
Update on this for anyone interested.  The correct way of achieving what I wanted is to use PageRefernce to pass the parameters to the new version of  the component.  Apart from using newer technology to achieve this it also means that the correct stylesheets are applied to the component when it is reloaded after the call.

LC1.cmp
<aura:component implements='flexipage:availableForAllPageTypes,force:appHostable,lightning:isUrlAddressable' access='global'>  <!-- lightning:isUrlAddressable is key -->
    <aura:attribute name="param1" type="String" default="AAA"/> 
    
    <lightning:navigation aura:id="navService"/>
    
    <aura:handler name="init" value="this" action="{!c.doInit}"/>
    
    <!-- Need this otherwise subsequent calls to the component will not pass new values e.g. Call once with param of 'A', use browser's back button. A subsequent
         call with a different param value will not be noticed by the second compoennt -->
    <aura:handler name="change" value="{!v.pageReference}" action="{!c.doInit}"/>  
    
    <div class="slds-box slds-theme_default">    
        <p>{!v.param1}</p>
    
        <p><a href="javascript:void(0);" onclick="{!c.changeParamLC}">Call Component with new parameters on new page</a> </p>
    </div>    
</aura:component>

LC1Controller.js
({
    doInit : function(component, event, helper) {
		
        // Get page reference which includes parameters passed in
        var pageReference = component.get('v.pageReference');
        // Check for nulls.  This will be the case when initially openning the component 
        if ($A.util.isEmpty(pageReference) || $A.util.isEmpty(pageReference.state) || $A.util.isEmpty(pageReference.state.c__param1)) {
          return;
        }
		
        // Populate the attribute with the parameter value
        component.set('v.param1', pageReference.state.c__param1)
        
    },

    changeParamLC : function(component, event, helper) {
		// Create the pageReference to open the component on a new page with the required parameter values
		// Different types of page references can be found at https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/components_navigation_page_definitions.htm
        var pageReference = {
            type: 'standard__component',
            attributes: {
                componentName: 'c__LC1',
            },
            state: {
                "c__param1": 'BBB'
            }
        };
        
        var navService = component.find("navService");
        event.preventDefault();
        navService.navigate(pageReference);
        
	}

})