In an LWC I need to perform some logic when a postMessage is received from an iframe. The logic needs to reference an api property of the LWC which is set by a parent component.
I want to supply a named function when I add the event listener so that the listener can later be removed.
Here's what I've tried:
import { LightningElement, api } from 'lwc';
export default class MikeComponentTwo extends LightningElement {
@api
someValue;
someFunction(event) {
alert(`Hello ${this.someValue} - ${this === window} - ${event.data}`);
}
connectedCallback() {
window.addEventListener("message", this.someFunction);
}
}
This produces
Hello undefined - true - {"token":"03ANYol..."}
So when someFunction
runs, it doesn't know about someValue
. I added in the check on this
and can see that this === window
.
How can I get around this
?
Best Answer
In writing out what I tried, and trying other things, I got it working. It's likely a common pattern, so here's the working version.
When the listener calls the function, it sets
this
in the function to the object that fired that event, so window in this case. That's not helpful as window doesn't know about someValue.Arrow functions to the rescue!
Remember that arrow functions do not have
this
. When you refer tothis
in an arrow function, "the lookup of this is made exactly the same way as a regular variable search: in the outer lexical environment."(1)So re-writing the function as an arrow function means that it can now see
someValue
, and we have a listener, which can later be removed because it calls a named function, which calls that function, which refers to a property in the LWC.This produces
Hello Mike - false - {"token":"03ANYol..."}
If I add a console.log into someFunction:
the console shows
so we can see that
this
is the component itself.The following resources helped with understanding
this
:(1) https://javascript.info/arrow-functions
https://stackoverflow.com/questions/34913744/window-addeventlistenermessage-myfunctionevent-doesnt-work
https://www.sitepoint.com/javascript-this-event-handlers/
https://www.quirksmode.org/js/this.html
This answer was posted on https://salesforce.stackexchange.com by Mike Arthur. Any other sites displaying this content have not contributed to it in any way.