For Android fusion chart showing html content in React Native - android

I have integrated fusion chart to my application in React Native. For iOS, Its working fine, But, In android while I tried to display graph, Its showing html content in the UI.
I have followed installation steps properly from github page.
//header declaration
const fusionChartiOSPath = require('../assets/fusioncharts.html');
const fusionChartAndroidPath = { uri: 'file:///android_asset/fusioncharts.html' };
//render method
<FusionCharts
type={type}
width={width}
height={height}
dataFormat={dataFormat}
dataSource={dataSource}
containerBackgroundColor={containerBackgroundColor}
libraryPath={
Platform.OS === 'ios'
? fusionChartiOSPath
: fusionChartAndroidPath
}
/>
But, In UI its showing like
<!DOCTYPE html>
<html>
....
Can anyone suggest me, Where I am doing wrong?

It's happening due to some file issue. Fixed

Related

Why does React Native Webview not load image from a URL

I have a website that loads images from the internet, I thought I could easily make a React App that just shows the webpage as a Web View
The Web Page loads up perfectly fine, and I added a log that shows that it does load the image URL's correctly.
But the Images don't show on the Android app. I don't know how to debug React Native Apps Properly
On the Web Page the image are shown through a CSS property 'background-image: url(image url)'
And I update that property, maybe that's is the source of the issue
This is the Web Site, it's made for mobile devices really and is still a WIP
https://praw.herokuapp.com/
What I have tried:
I used Android Studio to debug the APK and LogCat shows 1 error everytime I try change the Image
E/StudioTransport: JVMTI error: 103(JVMTI_ERROR_ILLEGAL_ARGUMENT)
Doing some searching online JVMTI_ERROR_ILLEGAL_ARGUMENT is an error that is caused because "The supplied memory buffer is too small."
That makes me think, React allocated memory for my app, but once I loaded a new image it didn't have enough memory to display it? What do you think?
That is all the info I could find on the error... Android Studio did not give me any other helpful info
Is this a bug maybe with React Native WebView? Should I raise a GitHub Issue?
Is there any other info I could share that may help?
My Entire React Native Code 😅
import React, { Component } from 'react';
import { WebView } from 'react-native-webview';
class App extends Component {
render() {
return (
<WebView source={{ uri: 'https://praw.herokuapp.com/' }}/>
);
}
}
export default App;
Try it with the View
<View style={{flex: 1, flexDirection: 'row'}}>
<WebView style = {{flex:1}} source={{ uri: 'https://praw.herokuapp.com/'}} />
</View>
or try to add <application android:largeHeap="true"> in android manifest
Fixed it, turns out http requests are a no no... I probably shouldn't do what I did, but I changed the image URLs from http to https...
You need secure URLs otherwise the image won't show up
The errors in LogCat are useless and had nothing to do with the error. I guessed this was the issue by reading the Java source code on Web Views. Going through that gave me some hints and it worked... yay I guess

Link Within an App with the React Native Render Html

In my expo / react app I have some HTML from a website that I'm pulling from an api. I'd like to use links within that html to link to pages within the app. Some example html...
responseHtml = "<p>this is a paragraph Some Page<p>"
then I was thinking I would do some string replace so that the html ends up looking like this...
responseHtml = "<p>this is a paragraph Some Page<p>"
Then I would render the content in my app and the links would work if I did something like this...
<HTML onLinkPress={(event, href)=>{Linking.openURL(href)}} html="{responseHtml}" />
I cannot seem to find the right href value to make a successful click to a page within the app. I've tried using the full path, exp://127.0.0.1:19200/Article/some-page, I've tried relative links like /Article/some-page, and I've tried setting a schema value to "myapp" in the app.json and linking to it with myapp://Article/some-page
Have you tried to parse it ? I would use the react-native-htmlview library. There you can customize the Link handler. So you could open the link or pass it down as prop.
Your code could be look like this:
import React from 'react';
import HTMLView from 'react-native-htmlview';
class App extends React.Component {
render() {
const responseHTML = ``;
return (
<HTMLView
value={htmlContent}
stylesheet={{
fontWeight: '300',
color: '#FF3366', // make links coloured pink
}}
/>
);
}
}
If you want to do any custom actions with your link it could look like this:
return (
<HTMLView
value={this.props.putyourhtmlhere}
onLinkPress={(url) => console.log('clicked link: ', url)}
/>
);
Hope that helps

Ionic 4 Loading Local resource not working on IOS

I'm trying to load a image from users phone, crop it and then display. Im using the webview plugin to do that. It works as intended on android but not on IOS.
I've tried this from another question, which resloves to file not found error
itemSrc = itemSrc.replace(/^file:\/\//, '');
I also looked at NormalizeURL but that does not seem to work with Ionic 4
Heres some code
this.imagePicker.getPictures(options)
.then((results: string[]) => {
results.forEach(res => {
this.crop.crop(res, {quality: 50})
.then(
data =>{
//this is extracting the URL
this.user.photos.push(this.webview.convertFileSrc(data));
},
After that, the UI should display the cropped image, which it does on android, but not on IOS.
I used safari dev tools to inspect and this is the error:
[Error] Failed to load resource: unsupported URL (unsafe:ionic://localhost/_app_file_/Users/radmac/Library/Developer/CoreSimulator/Devices/8E6A6BFA-66FA-4DB3-B556-BCE9E2EFE33A/data/Containers/Data/Application/C39D8D99-0F67-4D33-9195-EE2B4D4E4707/tmp/cdv_photo_024.jpg, line 0)
So, I found the solution for this. Before that, You can read this blog post which is really helpful if you want to understand more about ionic native and images.
https://ionicframework.com/blog/storing-photos-with-the-cordova-camera-and-file-plugins/
the solution was to just wrap the webview converted src with dom sanitizer, like so,
const resolvedImg = this.webview.convertFileSrc(data);
this.user.photos.push(<string>this.sanitizer.bypassSecurityTrustUrl(resolvedImg));
Make sure to import the dom sanitizer.
import {DomSanitizer} from "#angular/platform-browser";
...
constructor(private sanitizer: DomSanitizer){
...
}

ReactNative - Webview not executing injectedJavaScript on Android

I'm having trouble getting the Webview on ReactNative to execute the injected JavaScript on a physical Android device. I've scoured the web as far as I could over the past 2 days and still haven't found a solution. Results for testing are as follows:
iOS simulator - All good
iPhone - All good
Android simulator - All good
Physical devices, Sony Xperia Z2, Sony Xperia Z5 Compact and LG G4 - NOTHING
My Webview is defined as follows:
<WebView
style={styles.webView}
source={{
html: html,
baseUrl: 'web/'
}}
injectedJavaScript={'render(' + JSON.stringify(this.state.data) + ');'}
javaScriptEnabledAndroid={true}
scrollEnabled={false}
bounces={false}
renderLoading={() => <LoadingIndicator />}
/>
I've tried specifying javaScriptEnabled as well, to no avail. I also tried smaller scripts to just colour elements on the page or post a message back to the app using window.postMessage, but nothing happens. I need to inject the data to the HTML, which will render graphs for me based on the supplied data. My last resort is to manually construct the HTML with the data appended as part of the markup being supplied to the Webview, but I'd really like to keep it simple and just get it to work the way it should.
I'm using the latest version of ReactNative (0.41) and the phones are running Android 6+.
I just discovered that the Android WebView appears to inject any JS as a single line, even if it includes line breaks. That means that missing semicolons can definitely cause issues, or, in my case, comments delimited by //. Using /* and */ for comments got my injected JavaScript working again.
Well, after leaving this question open for some time and finding a (not so elegant) solution to the problem, I decided I'd share what I ended up doing:
I declared the HTML to be passed to the WebView in a constant string along these lines: const html = '<html>...<script>...[INJECTEDSCRIPT]</script></html>';
I retrieved the data in the componentDidMount() event of the React component's lifecycle and set a state variable for it using this.setState({ data: retrievedData });
This, of course, forced the component to re-render itself, after which I now have the data available to "pass" to the WebView
Seeing as I couldn't find any elegant or usable way of using the injectedJavaScript property to work the way I want it to (as stated in the question), I resorted to replacing the [INJECTEDSCRIPT] value in the HTML constant with the serialized data.
Not the most elegant solution, I know, but it's the only one I could get working reliably across a multitude of devices and emulator configurations. Sample, edited for brevity, as below:
const html = `
<!DOCTYPE html>
<html>
<head>...</head>
<body>...</body>
<script>
var render = function (data) {
...
};
[INJECTEDSCRIPT]
</script>
</html>`;
export class GraphComponent extends Component {
constructor(props) {
super(props);
this.state = {};
}
componentDidMount = () => {
SERVICE.getData().done((data) => {
this.setState({ data: data });
});
}
render = () => {
if (!this.state.data)
return <LoadingIndicator />;
let serializedData = JSON.stringify(this.state.data);
return
<WebView
style={styles.webView}
source={{
html: html.replace('[INJECTEDSCRIPT]', 'render(' + serializedData + ');'),
baseUrl: 'web/'
}}
scrollEnabled={false}
bounces={false}
renderLoading={() => <LoadingIndicator />}
/>;
}
}
I have been struggling to get Javascript (pre-embed and injected) to be executed as well. So far, a simple and better solution is to use WebViewBridge. After, everything worked as expected. Here a link to the package: cnpmjs.org/package/react-native-webview-bridge.
Here a demo:
import React, {
Component
} from 'react';
import PropTypes from 'prop-types';
import {
Platform,
WebView,
ActivityIndicator,
} from 'react-native';
import WevViewBridge from 'react-native-webview-bridge';
// TODO: Keep in mind that you should ALWAYS edit
// two separate file and keep them matched.
const IOS_WEB_PAGE_SOURCE = './webPage/wordBody.html';
const ANDROID_WEB_PAGE_SOURCE = 'file:///android_asset/webPage/wordBody.html';
export default class WordBody extends Component {
static propTypes = {
data: PropTypes.object.isRequired,
}
_injectedScript = `
(function(){
let data = ${JSON.stringify(this.props.data)};
refresh(data);
})();
`;
render() {
/*
* We are using Platform.select here for two reasons:
* 0. Everythig work fine for IOS using `WebView` from RN
* 1. Android doesn't load web ressource with `require`
* 2. On Android, `WebView` from react-native doesn't
* execute JavaScript so we use `WebViewBridge`.
*/
return Platform.select({
ios: (<WebView
style = {{backgroundColor: 'rgba(0, 0, 0, 0)', flex:1,}}
scalesPageToFit
source = {require(IOS_WEB_PAGE_SOURCE)}
javaScriptEnabled={true}
originWhitelist={['*']}
injectedJavaScript = {this._injectedScript}
renderLoading={() => <ActivityIndicator/>}
/>),
android: (<WevViewBridge
style = {{backgroundColor: 'rgba(0, 0, 0, 0)', flex:1,}}
scalesPageToFit
source = {{uri:ANDROID_WEB_PAGE_SOURCE}}
javaScriptEnabled={true}
// originWhitelist={['*']}
injectedJavaScript = {this._injectedScript}
renderLoading={() => <ActivityIndicator/>}
/>)
});
};
}

MapQuest : MQ is not defined

I had to take over and android app working with phonegap - leaflet/MapQuest/openstreetmap
It broke because MapQuest stopped direct access to tiles and the map wouldn't show up anymore.
I then added the key and modified the code as suggested here : https://developer.mapquest.com/documentation/leaflet-plugins/maps/
I use this code :
<link rel="stylesheet" href="scripts/leaflet-0.7.7/leaflet.css" />
<script src="scripts/leaflet-0.7.7/leaflet.js"></script>
<script src="https://www.mapquestapi.com/sdk/leaflet/v2.s/mq-map.js?key=validKeyNumberThatIWontReveal"></script>
In the following structure :
And my JS :
var popup = L.popup();
var geolocationMap = L.map(b, {
layers: MQ.mapLayer(),
center: [40.731701, -73.993411],
zoom: 12
});
Which workout well when I try it on a browser.
But when I compile on my android phone with Android studio I get this error :
'MQ is not defined'
It used to work fine with scripts/vendor/leaflet-0.7.
My wild guess would be : it somehow doesn't reach the library scripts/leaflet-0.7.7 but I can't see why.
I ended up having 2 problems, one of my own and one that could help any reader :
I wasn't declaring the leaflet script at the right place (the page I declared it in). For reference see : https://developer.mapquest.com/documentation/leaflet-plugins/open/
Problem of URL described there : mapquest direct tile access discontinued
For the sake of easiness this is the answer
It's as simple as changing your tileUrl.
Replace this:
var tileUrl =
'http://otile{s}.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.png?x';
with this:
var tileUrl = 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
Then use as before:
L.tileLayer(tileUrl, { }).addTo(map);
#Joel Harris

Categories

Resources