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
KellymtKellymt 

Receiving a window.postMessage even from Lightning component

I have a lightning component which invokes a third party popup window as a lightbox. The window is served from another domain.
I would like for when that thrid party window closes to call a JavaScript method in my Lightning component to receive some data. 

The best way I found to pass the results is via window.postMessage because the thirda party window and the lightning components are from different domains. 
The quiestion I have is how to receid that postMessage even from my Lightning component. 

I tried adding the below method to my Lighting component's controller but it did not work: 
 doInit : function(component, event, helper) {
        var listener = function(event) {
           //Do work here
       }
        if (addEventListener){
              addEventListener("message", listener, false);
        } else {
              attachEvent("onmessage", listener);
        }
    },

Could you please help me figure this out.
Rajiv Penagonda 12Rajiv Penagonda 12
Kellymt, the way I see it, there are two halves that needs to be addressed here. Details below:

First Half: The third party popup should support sending message back to your window/script. Ideally if you are using a third party tool, they should provide you a hook/callback function or other API to enable/register this.
Second Half: You have to register your script to listen to "message". The idea is that the third party tool will send you a message indicating that dialog is closed and you can take actions accordingly. Documentation here (https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage).

Do note: I am assuming that by "window" you are referring to an actual browser popup/new dialog.

If the third party does not offer a hook/callback to achieve this then you could try the following:
1. Create a helper VF page that will inturn launch the third-party script/page inside an iframe. Design this helper VF page to send message back to your source page which can process the message.
2. Invoke your helper VF page from your source page instead of the actual third party URL that resides outside your domain.
3. In your helper VF write scripts to listen to window closed event, and if detected, use "window.postMessage" to send the event to your source/origin page.

Hope this helps.
KellymtKellymt
Rajiv thank you very much for your response. 
I do know how postMessage works and I do control the third party (maybe that meks it not a third party) application thus it is sending the message and I tested it with Visualforce. 
The piece I do not know is how to register to receive the post message from within my LIighting component because registering in the controller in the doInit method with the code I pasted above did not work.
Rajiv Penagonda 12Rajiv Penagonda 12
See if the following works:
 
doInit : function(component, event, helper) {
	var listener = function(event) {
	   //Do work here
	}
   
	if(window.addEventListener !== undefined) {
		window.addEventListener("message", listener, false);
	}
	else {
		attachEvent("onmessage", listener);
	}
}

 
KellymtKellymt
Thanks you. I did try it with
window.

but still no luck. In fact that was the original code I tried it with ( I should have probably said that in my original question).

Do you have other ides?

 
Matt Albertson 9Matt Albertson 9

Hey Kellymt, 

Did you ever find a resolution to this? I'm in a similar situation and I can't figure it out.

Thanks!

Azhar BeebeejaunAzhar Beebeejaun
Hello, any update? I need to listen to message events.
Douglas C. AyersDouglas C. Ayers
In your Lightning Component, you may need to try and access the window element in your renderer (https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/js_renderers.htm) rather than your controller's init method (https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/js_cb_init_handler.htm?search_text=init).

The controller's init method is called before all the DOM elements have been inserted into the component, and I've noticed that it may hide some implicit elements like window. See rendering lifecycle documentation (https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/components_lifecycle.htm).

Here's example code (https://github.com/DouglasCAyers/sfdc-lightning-data-tables-component/blob/master/src/aura/DataTableCmp/DataTableCmpRenderer.js) where I added event listener for "onscroll". I did this in the renderer resource of my component.
 
({
    afterRender : function( component, helper ) {

        this.superAfterRender();

        // this is done in renderer because we don't get
        // access to the window element in the helper js

        window.onscroll = function() {
            // do something
        };

    }
})



 
Nilesh DetheNilesh Dethe
Hello Kellymt, here is good Salesforce blog which nicly explain the Lightning Component vs Visualforce page communication using window.postMessage method (https://developer.salesforce.com/blogs/developer-relations/2017/01/lightning-visualforce-communication.html). This also has source code of example explain on git hub. Thanks !