In this post :
https://www.wix.com/code/home/forum/questions-answers/postmessage-onmessage-no-longer-working
I noted the current erratic behaviour of onMessage when listening to a postMessage from HTML-component. I have used this for over half a year and always worked OK. But now I sometimes get a message from the component but mostly not.
I put the following on the Wix side as a test:
- a html-component called html1
- this code on the Wix side:
$w.onReady(function () {
$w(“#html1”).onMessage( (event) => {
console.log(“in w:onMessage”);
});
});
export function html1_message(event, $w) {
console.log(“in w:onMessage thru props”);
}
- the following html in the component
<!doctype html>
The following happens:
- preview mode no longer displays console.log´s at all
- Publish Mode shows the two messages from the html-code, but not the console.log from the Wix site under the $w(“#html1”).onMessage( (event) => {
that is to say: 9 times out of 10 I don´t get it, 1 time I do. If I don´t console also displays "Slow network detected messages.
- I noticed the html-component has a onMessage event in the Property Panel (never saw that before). When I put a console.log in there, it ALWAYS displays.
Question: why does the $w(“#html1”).onMessage( (event) => { no longer work reliably?
Hey
It must be some tricky shitty thing going on, I just checked my maps and they do crash every time and then. Have you tried to use async in functions in Wix Code and await before console log?
Andreas, I am so p$%&/ed off with Wix at this very moment, I am going to leave it till tomorrow before I write something I will regret. But yes, there is something really ugly going on.
Send me an site invitation to andreas@pilgrimsbo.se and I will look at it with my tired eyes 
My problems still is that the .onMessage is not raised every time, while the function message is.
The console.log for the .onMessage is “in w:onMessage” and thru the function (property panel) “in w:onmessage thru props”
I have attached 4 fotos to illustrate what is happening:
- opera, after 17 hours of not doing anything. I run the page in publish mode and the both are raised
- opera, immediate reload. “w:onMessage” is not raised
- firefox, load fresh: “w:onMessage” is not raised
- chrome, same: “w:onMessage” is not raised
Can somebody please tell me what is happening here?
Hi Giri and Andreas,
I’ll try to shortly explain a basic principle of iframes:
Loading an iframe is an asynchronous task, meaning you don’t know the exact point that this will happen (and can’t assume that page is ready when iframe is finished loading).
So if I’m trying to draw a timeline, here are two options:
- page starts loading → iframe starts loading → page finished loading → iframe finished loading
- page starts loading → iframe starts loading → iframe finished loading → page finished loading
Note: since iframes are inside a page, the page loading process fires up the iframe loading process so you would expect (and thus you can see) that most times, the page will finish loading before the iframe.
So, I’m guessing what you’re trying to achieve should happen when both are ready.
I’d take the following approach:
On your global scope, set a variable:
let hasHappened = false;
Then, in $w(‘#html1’).onMessage do:
$w("#html1").onMessage( (event) => {
console.log("in w:onMessage");
hasHappend = true;
});
in $w.onReady:
$w.onReady(function(){
if(!hasHappend) {
$w("#html1").postMessage('StartNow');
}
});
And inside your html component add a code that will deal with that using ‘window.onmessage’.
Hope this makes sense and helps 
Liran.
Liram, thank you for your time to answer, but what you describe is not the problem. I am well aware of the async nature, as I have described ages ago here:
I describe just I you advise: in the html body.onLoad you first send a message that the component is ready and THEN you send the content for the iframe.
The problem is that this used to work reliably till last monday. I have been developing something new with the html-comp (using the above technique) and all worked beautifully till Friday. Monday I ran it again, and everything started to go wrong.
The cause of the problem is that, in Publish Mode, the html-component still sends a postMessage (as described below), but is not picked up on the Wix side reliably every time.
To cut to the chase: could you explain why function sendMessage (defined from the html-component´s property panel) picks it up every time, but the $w(“#html1”).onMessage does not?
This never used to happen and I fear you have updated the component (that “iframe loaded” wasn´t there last week, I have been staring at that console window for 2 weeks).
In short: existing, working code suddenly broke with the above as its cause.
If you think; then why not use the function message: that one is often raised BEFORE $w.pageload and dataset.onload, so the component might be ready, but NOT the main program. I cannot put the function inside the page.onload, only $w.onMessage can do that.
I hope I have made it as clear as possible, if not, let me know.
It might be that I have attacked it from the completely wrong side, but looking at Liram´s example code, there is one thing that I do not understand: in the $w.onReady(function() you send a message to the component that is not ready yet, because `hasHappend’ is still false.
But that message will never get there if it is not ready. Shouldn´t you ‘wait’ for the html-component to be ready and if so, how would you do that? Put everything inside the .onMessage? But then, how do you know the $w.onReady(function() is ready? As Liram said; the component might be ready, but the page might not be.
In short: how do you wait till BOTH are ready?
Ok, I got the misunderstanding…
When ‘hasHappened’ is false, it doesn’t actually mean that the component is not ready. It only means that ‘$w(‘html1’).onMessage()’ has not been called.
This goes back to the explanation of async.
So, let’s assume that the iframe is loaded before the hosting page is ready, then the iframe shoots ‘I’m ready’, but since the page is not ready, and ‘$w(‘html1’).onMessage’ is still not set, than no one catches the ‘I’m ready’ message.
Sadly, we currently don’t have an ‘onReady’ event for iframes, so the code I’ve written is actually making a fake ‘wait for ready’ affect because of of the following will occur:
- page laded → hasHappend is false but iframe not ready so communication with it does nothing → onMessage get set → iframe loaded → iframe shoots ‘I’m ready’ → onMessage catches it
- iframe loaded → iframe shoots ‘I’m ready’ → no one catches → page is loaded and hasHappened is false → start communicating with iframe.
Hope this helps…
Liran.
OK, thanks, that makes very much sense. Thank you. I´ll give it a try.
Liran, I got round to implementing this, but I think the whole testing for hasHappened is superfluous.
hasHappened only gets set to true inside
$w(" #html1 ").onMessage( (event) => {
but that $w(" #html1 “) is inside the $w.onReady, right? So in order to get there, $w.onReady must have been already called, message is sent, picked up or not, and if not, the message from the html-component that it is ready is received, message is sent, picked up, hasHappend set to true, but this condition will never be tested again because … $w(” #html1 ") was inside $w.onReady and, to refer to a haiku , that water had already moved on.