React Native load dynamic content onto webview - react-native

Currently I am loading a html file from my android assets folder into webview.
dashboard.html file contains some scripts.
if its static it works fine.
<WebView
ref={(component) => (this.webview = component)}
style={{ height: height * 1.3 }}
javaScriptEnabled={true}
domStorageEnabled={true}
source={{uri:'file:///android_asset/graph/pages/dashboard.html'}}
startInLoadingState={true}
javaScriptEnabledAndroid={true}
mixedContentMode={'compatibility'}
/>
But I need to dynamically update a variable in my script.
How can I access scripts placed in assets folder from react-native component.

You can use forceUpdate();
e.g.
<webView source={{html: this.state.html}}></webView>
onTestBtnClicked() {
const html = '<div>test1</div>';
this.setState({ html });
this.forceUpdate();
}

You can't access and update a script file but maybe you can run your script or extra code once the WebView is loaded using the injectedJavaScript prop
Example:
const injectedJs = `
alert("My custom code will go here!");
`;
return (
<WebView
ref={(component) => (this.webview = component)}
style={{ height: height * 1.3 }}
javaScriptEnabled={true}
domStorageEnabled={true}
source={{uri:'file:///android_asset/graph/pages/dashboard.html'}}
startInLoadingState={true}
javaScriptEnabledAndroid={true}
mixedContentMode={'compatibility'}
injectedJavaScript={injectedJs}
javaScriptEnabledAndroid={true}
/>
);

Related

React native webview - this.webview doesn't exist

I am pretty new to react-native. Currently, I am developing an app with react native web-view.
My requirement is to open external links of the app in a chrome tab. To achieve that I used the following code.
<WebView
source={{uri: catalog_url}}
onNavigationStateChange={(event) => {
if (!event.url.includes(home_url)) {
this.WebView.stopLoading()
Linking.openURL(event.url);
}
}}
/>
But I found that the highlighted line is not working currently.
Any reference to this.WebView line gives an error saying
this.WebView doesn't exist.
I need an alternative to this.WebView.
If you want to reference of this webview. First, you must assign a reference like that.
<WebView
ref={webview => this.WebView = webview}
source={{uri: catalog_url}}
onNavigationStateChange={(event) => {
if (!event.url.includes(home_url)) {
this.WebView.stopLoading()
Linking.openURL(event.url);
}
}}
/>
So you have missed the ref props from the WebView component
Solution
<WebView
ref={(ref) => (this.WebView = ref)}
source={{ uri: catalog_url }}
onNavigationStateChange={(event) => {
if (!event.url.includes(home_url)) {
this.WebView.stopLoading();
Linking.openURL(event.url);
}
}}
/>
If you need more reference about how to use WebView in RN visit here

React native webview files are not loading in ios device, but loading fine in simulator

Im storing the local file in xcode,files are loading in simulator but not loading in ios device
im using react-native-webview version 5.0.1, in my webview im passing sourse as {uri: 'ICF-Package/ICFPackage/index.html'}
<WebView
source={Platform.OS === 'ios' ?
{uri: 'ICF-Package/ICFPackage/index.html'} :
{ uri: 'file:///android_asset/ICF-Package/ICFPackage/index.html' }
}
ref={(webView) => this.webView = webView}
originWhitelist={'["*"]'}
javaScriptEnabled={true}
domStorageEnabled={true}
startInLoadingState={true}
useWebKit = {true}
//scalesPageToFit={true}
scrollEnabled={false}
onLoad={() => this.sendPostMessage()}
allowFileAccess={true}
allowUniversalAccessFromFileURLs={true}
allowFileAccessFromFileURLs={true}
allowsInlineMediaPlayback={true}
mediaPlaybackRequiresUserAction={true}
/>
im not getting any error message but files are not loading in real device
Maybe that helps you to debug WebViews a bit deeper if running at your Device: https://stackoverflow.com/a/48572797/1256697
But as little Workaround for local files, you could try to use the 'html' parameter instead the 'uri' Parameter for IOS:
const myHTML = require('./ICF-Package/ICFPackage/index.html');
<WebView
source={PolicyHTML}
style={{flex: 1}}
/>
Also see: https://aboutreact.com/load-local-html-file-url-using-react-native-webview/
But maybe the cleanest way to solve it for IOS is to put a copy of your html-File in Project > resources > index.html and link it like that with your Webview:
<WebView
style={{flex: 1}}
originWhitelist={['*']}
source={'./resources/index.html'}
javaScriptEnabled={true}
domStorageEnabled={true}
/>

React Native image not showing or blank using Laravel Localhost source

I am trying to show images fetching from api. and to show images from localhost laravel project. Running my emulator on Genymotion. how do I do that?
Online images are working like fb fevicon. and I am not using the localhost:8000 link for images as I am testing on Genymotion
// URL to fetch apis
export const URL = 'http://10.0.3.2:8000';
// Showing/Displaying my image in React native
if(list && list.length > 0) {
const listAfterPictures = list.map((item, index) =>
<Image
key={ index }
source={{ uri: URL + index.image_name }}
style={{ width: 300, height: 300 }}
/>
);
return (
<View>
{listAfterPictures}
</View>
)
}
I also tried to put width and height in source like:
<Image
key={ index }
source={{ uri: URL + index.image_name, width: 300, height: 300 }}
/>
Any Suggestions?
Please console log URL + index.image_name and check if all back slashes are there. And make sure to include the file extension e.g .jpg .png

Get HTML content of webpage with webview

I want to get html code with webview in react native my current code only can call alert function after its injected. i want to get a specific div html content.
const jsCode = "window.postMessage(alert(document.getElementById('result')))"
<WebView
style={{width:Dimensions.get('window').width,height:Dimensions.get('window').height}}
javaScriptEnabled ={true}
injectedJavaScript={jsCode}
source={{uri: this.state.uri}}
/>
window.postMessage causes the WebView.onMessage-handler to get called with the data.
So this should work:
const jsCode = "window.postMessage(document.getElementById('gb-main').innerHTML)"
<WebView
javaScriptEnabled={true}
injectedJavaScript={jsCode}
source={{uri: 'http://www.google.com/'}}
onMessage={event => console.log('Received: ', event.nativeEvent.data)}
/>

How to get the html source of WebView object in react native

I'm trying to access the HTML source code of a 3rd party web page to read a specific DOM element value of a page which is loaded in WebView component in react-native.
<WebView
source={{uri: 'https://www.amazon.com'}}
/>
and Suppose there's a DOM element like this:
<span class="price bold some-class-name">$459.00</span>
I also tried this component but could not do that:
https://github.com/alinz/react-native-webview-bridge
Is there any way to get the current HTML source code of page inside a WebView and Read specific DOM element value?
Looks like this functionality was added in React Native v0.37. Adding an onMessage parameter will inject a postMessage variable into your WebView. You can then just inject JavaScript as normal, select your element and postMessage it back.
render (
const jsCode = "window.postMessage(document.getElementsByClassName("price bold some-class-name"))"
return (
<View style={styles.container}>
<WebView
source={{uri: "http://..."}}
onMessage={this._onMessage}
injectedJavaScript={jsCode}
/>
</View>
);
)
The answer by Brian F is great and helped me a lot. There is just one thing missing. You need to append ReactNativeWebView to the postMessage function.
So it would look like
render (
const jsCode = "window.ReactNativeWebView.postMessage(document.getElementsByClassName("price bold some-class-name"))"
return (
<View style={styles.container}>
<WebView
source={{uri: "http://..."}}
onMessage={this._onMessage}
injectedJavaScript={jsCode}
/>
</View>
);
)
In my experience, It will work well, because I've tried to get product information from Amazon and Taobao, Rakuten.
_onMessage = (message) => {
// you can put processing code here.
}
render (
const jsCode = "window.ReactNativeWebView.postMessage(document.getElementsByClassName("class name"))"
// or you can use `document.querySelector("element query")` instead of `document.getElementsByClassName("class name")`
return (
<View style={styles.container}>
<WebView
source={{uri: "url here"}}
onMessage={this._onMessage}
injectedJavaScript={jsCode}
/>
</View>
);
)
For those who are still not getting then try this for the latest react-native
window.ReactNativeWebView.postMessage(document.getElementById('id_here').innerHTML);
const INJECT_JS = `window.ReactNativeWebView.postMessage(document.getElementById('id_here').innerHTML);
alert("Hel0....")
`
return (
<View style={styles.container}>
<WebView
source={{uri: "http://..."}}
onMessage={event => {
console.log(event.nativeEvent.data);
}}
injectedJavaScript={INJECT_JS }
/>
</View>
);
<WebView
source={{html: "<span class="price bold some-class-name">$459.00</span>"
/>
or you can right your template into a constant, then do this:
const HTMLTemplate = `<span class="price bold some-class-name">$459.00</span>`;
<WebView
source={{html: HTMLTemplate}}
/>