2

I have to load react js app in iframe and parent application is sending data to iframe react app using below code:

  const myiframe = document.getElementById('myIframe');
  myiframe.contentWindow.postMessage('message', '*');


  <iframe id='myIframe' name="my-iframe" src="http://localhost:3000" ></iframe>

In iframe app I am trying to receive data:

useEffect(() => {
    window.onmessage = function (event) {
      console.log('event received')
    }
  }, []);

But window.onmessage never triggers or triggers intermittently.

I checked by keeping window.onmessage out of useEffect but it is not working.

Has anyone faced this issue? Need help.

Thanks.

Always_a_learner
  • 4,585
  • 13
  • 63
  • 112
  • Hi, do you want to try another way? (instead of send message to iframe ) or you have to use send message ? – Babak Yaghoobi Mar 31 '21 at 12:35
  • I have to communicate with iframe. postMessage is implemented in parent app so I have to add window.onmessage or window.addEventListner('message'). What other way is there? – Always_a_learner Mar 31 '21 at 12:38
  • in your react source in componentDidMount() {window.parent.callMe = myFunc} and in your parent app just call window.callMe(...your-parameters) if you interested to more, I can show you full sample code – Babak Yaghoobi Mar 31 '21 at 12:42
  • Thanks, My parent is written in angular. iframe app is in react. Please share example if possible. – Always_a_learner Mar 31 '21 at 12:43

1 Answers1

0

This is simple code, not important what is in your iframe and what is in your parent app, we need just a share a function on a global variable like window

in you parent app just call :

window.callMe('Hello world');
or
window.callMe({status:true, message:'hello world'});

and in your iframe (react in your sample) just define callMe on parent window :

myFunc=(data)=>{
    console.log(data);
}
window.parent.callMe = myFunc;

sample code:

import React from "react";
import ReactDOM from "react-dom";

import "./styles.css";

function App() {
  const callIframeFunc = () => {
    window.callMe("Hello");
  };
  return (
    <div className="App">
      <h1>React rel with iframe Demo</h1>
      <iframe
        id="unqiframe"
        title="a"
        srcDoc="<div><script>function myFunc(data){document.getElementsByClassName('testp')[0].innerHTML = 'received data : '+data} window.parent.callMe = myFunc;</script><p class='testp'>No data</p></div>"
        allow="autoplay"
      ></iframe>
      <div>
        <button onClick={callIframeFunc}>Call iFrame Func</button>
      </div>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

DEMO

Babak Yaghoobi
  • 1,892
  • 9
  • 18
  • Thanks, but I am getting Property 'callMe' does not exist on type 'Window & typeof globalThis' error message. – Always_a_learner Mar 31 '21 at 12:57
  • can you share me you code ? where you defined callMe ? – Babak Yaghoobi Mar 31 '21 at 12:58
  • I think you are using TypeScript if true then try define like : https://stackoverflow.com/questions/12709074/how-do-you-explicitly-set-a-new-property-on-window-in-typescript or this : https://stackoverflow.com/questions/56457935/typescript-error-property-x-does-not-exist-on-type-window – Babak Yaghoobi Mar 31 '21 at 13:04
  • 1
    Hi Babak, thanks for helping out. I was trying some other solution and while debugging I find out that postMessage is running before window.onmessage that is why the event is not receiving. – Always_a_learner Mar 31 '21 at 14:02