Nathan Tew
Nathan Tew

Reputation: 747

window.postMessage throws undefined error even though I checked that it is not undefined

I have a React webapp running inside a webview in a React Native app. The React Native side injects javascript to set window.postMessage like so:

<WebView
  injectedJavaScriptBeforeContentLoaded={`
    (function() {
      window.postMessage = function(data) {
        window.ReactNativeWebView.postMessage(data);
      };
    })()
    window.isInApp=true;
    true;`
  }
/>

Then, I call window.postMessage() in the React webapp to make the React Native app react to certain button presses:

<Button
  onClick={() => {
    if (window.isInApp) window.postMessage();
    else navigate("/my-trips");
  }}
>
  Exit
</Button>;

(I know that postMessage() is supposed to require arguments, but) This works everywhere in my React webapp, except for one particular page. At first, I get the error

Script error.

As well as

A cross-origin error was thrown. React doesn't have access to the actual error object in development.

So, to see the error, I wrapped the function call in a try-catch block, then displayed the error in an alert:

<Button
  onClick={() => {
    try {
      if (window.isInApp) window.postMessage();
      else navigate("/my-trips");
    } catch (e) {
      alert(e);
    }
  }}
>
  Exit
</Button>;

Running on an Android Samsung A54, I get this:

TypeError: Cannot read properties of undefined (reading postMessage)

And on an iOS iPhone 8, I get this:

TypeError: undefined is not an object (evaluating 'window.ReactNativeWeb-View.postMessage')

enter image description hereenter image description here

So then, I added some if conditionals to ensure window was not undefined, and also displayed window in some alerts before and after calling window.postMessage():

<Button
  onClick={() => {
    try {
      alert(`window: ${window}
        window.postMessage: ${window.postMessage}`)
      if (window && window.postMessage && window.isInApp) window.postMessage();
      else navigate("/my-trips");
    } catch (e) {
      alert(`${e}
        window: ${window}
        window.postMessage: ${window.postMessage}`);
    }
  }}
>
  Exit
</Button>;

However, I get the exact same error message, which claims that window is undefined, even though I check that it isn't undefined before AND after calling window.postMessage(). I also tried using window.postMessage(true, "*") just so I didn't have no arguments, but to no avail. I also don't see anything different about this particular page that can be remotely related to making window have an ephemeral superstate of existence. It's almost an exact replica of another page where the same thing works.

enter image description hereenter image description here

How is this possible? Why does it seem like window is only undefined when I call window.postMessage(), but is not undefined in the if checks and the alert dialogues? Almost like some double-slit-experiment-electrons behaviour type shit? Wtf is this?

(I know I should make a minimal reproducible example but that's gonna take a lot of time I don't have to spare at the moment. Hoping that maybe someone knows the explanation/fix before I resort to that.)

Upvotes: 0

Views: 338

Answers (0)

Related Questions