0

I have created a webview in my react-native component then i wanted to use postMessage to send data and read it through OnMessage . I don't know actually if the problem was in my postMessage or in my onMessage option of the webView . Can you tell me where is the problem please ? Here is my app Component :

      let Script1 = `
      var data = {
      message : "OnFocusEvent"
        };
      window.postMessage(JSON.stringify({data}),"*");
         `;
     export default class App extends Component {
      constructor(props) {
      super(props);}
      render() {
       return (
       <View style={styles.container}>

      <RNEnhanceWebview
      ref={ref => (this.webView = ref)}
      style={{ flex: 1 }}
      source={{
        html:
          ' </br></br></br></br><form> <input id="input" class="input" 
      type="text" placeholder="name"/></form>'
      }}
      keyboardDisplayRequiresUserAction={false} //ios
      autoFocus={true} //android
      injectedJavaScript={Script1}
      automaticallyAdjustContentInsets={false}
      allowFileAccessFromFileURLs={true}
      scalesPageToFit={false}
      mixedContentMode={"always"}
      javaScriptEnabled={true}
      javaScriptEnabledAndroid={true}
      startInLoadingState={true}

      onMessage={event => {
        console.log(event.nativeEvent.data);
        console.log(JSON.parse(event.nativeEvent.data));
      }}
      onLoad={() => {}}
    />
      </View>
       }

Do you have any suggestion to show my message data ?

  • you have named your script InjectScript1 but on your WebView you're using it as Script1. Try injectedJavaScript={InjectScript1} to see if it works – needsleep Dec 21 '18 at 13:54
  • sorry ! yup i tried it but it doesn't work –  Dec 21 '18 at 13:56

2 Answers2

1

You are right, it seems that your code doesn't work on Android but works fine on iOs...

This is a strange one, it looks as if the postMessage doesn't work on the first page load, but if you call it with a delay, like onFocus it works as expected.

For example try this script:

let Script1 = `
    document.getElementById("input").addEventListener("focus", function() {  
      var data = {
          type: "OnFocusEvent",
          message : "OnFocusEvent"
      };
      window.postMessage(JSON.stringify({data}),"*");
    });

    document.getElementById("input").addEventListener("blur", function() {  
      var data = {
          type: "OnBlurEvent",
          message : "OnBlurEvent"
      };
      window.postMessage(JSON.stringify({data}),"*");
    });
`;

onMessage={event => {
    console.log(event.nativeEvent.data);
    console.log(JSON.parse(event.nativeEvent.data));
    const messageData = JSON.parse(event.nativeEvent.data);
    const messageType = messageData.type;

    switch(messageType) {
        case "OnFocusEvent":
         console.log("Do whatever you want onFocus")
         break;
        case "OnBlurEvent":
         console.log("Do whatever you want onBlur")
         break;
        default:
         console.log("do nothing");
         break;
    }
}}

Here's the example on snack: https://snack.expo.io/rkANOd9lN

Hope it helps :)

needsleep
  • 2,685
  • 10
  • 16
  • thank u for your help i tried your solution but it doesn't work for me i am really confused because i can't find where is the problem exactly –  Dec 21 '18 at 15:06
  • Sorry for the late response, have you tried the snack i have in my answer? If you open it, open the logs console on the bottom of the page and every time you try to type in the input it will display the data you sent over postMessage. Also, are you trying this on iOs or Android? – needsleep Dec 22 '18 at 08:58
  • Good morning , thank you for your response. yup i tried snack console it's logging data but with visual code the same code compiled on a chrome browser it doesn't show anything on its console –  Dec 24 '18 at 08:32
  • You know it works but when i remove window.postMessage . So the problem is surely coming from window.postMessage –  Dec 24 '18 at 08:55
  • That is very strange... Maybe instead of a console.log do an alert, and also try to run it on a real device. For me it works, the only problem is that it doesn't work on window load and it needs a timer or a special event like onFocus to be called. – needsleep Dec 24 '18 at 09:03
  • Thank you so much for your help it works but with alert . Have a nice day –  Dec 24 '18 at 12:28
  • sure, go ahead :) – needsleep Dec 24 '18 at 14:27
  • okey when i focus the input it dispatchs an action in the onMessage : i change the state of a variable focused to true and now i want to do the same with onBlur(the same input) to change an other time the state of my variable focused to false . Can i do it ? How can the onMessage support two actions at the same time (two scripts) ? –  Dec 24 '18 at 14:46
  • ah, it's easy! You will add a property "type" to your data. So type can be "onFocus" or "onBlur" for example. Inside the onMessage function you will check the "type" and will act accordingly, I will update my answer in a bit to demonstrate this – needsleep Dec 24 '18 at 15:47
  • Here's a comprehensive implementation of this with a download link: https://stackoverflow.com/questions/41753104/how-do-you-use-webmessageport-as-an-alternative-to-addjavascriptinterface/60292598#60292598 – user2288580 Feb 28 '20 at 08:14
0

change this

window.postMessage(JSON.stringify(data))

to this

window.ReactNativeWebView.postMessage(JSON.stringify(data))