React-native Protected member is not accessible when using this.setState() - react-native

I am new to react native. Please help to solve this. where i have been wrong ? please point out and correct me.. Thank you so much
import React, {Component} from 'react';
import {Alert,View,Image} from 'react-native';
import ImagePicker from 'react-native-image-picker';
import {Button} from "../components/common";
class ImageSelect extends Component {
constructor(props) {
super(props);
}
state = {
ImageSource: null,
imageBase: null,
whichScreen: null,
};
showPicker() {
const options = {
quality: 1.0,
maxWidth: 500,
maxHeight: 500,
storageOptions: {
skipBackup: true,
path: 'images'
}
};
ImagePicker.showImagePicker(options, (response) => {
console.log('Response = ', response);
if (response.didCancel) {
console.log('User cancelled image picker');
}
else if (response.error) {
console.log('ImagePicker Error: ', response.error);
}
else if (response.customButton) {
console.log('User tapped custom button: ', response.customButton);
}
else {
let source = {uri: response.uri};
// You can also display the image using data:
// let source = { uri: 'data:image/jpeg;base64,' + response.data };
Alert.alert(source);
this.setState({
imageSource: source
});
}
});
};
showAlert(){
Alert.alert("Picked");
}
render() {
return (
<View>
<Button
buttonText={"Pick"}
onPress={this.showPicker.bind(this)}
/>
<Image
source={this.state.imageSource}
style={{width: 50, height: 50,}}
/>
</View>
);
}
}
export default ImageSelect;
I want to pick the image using existing library Image Picker.. and I need to save the source to the state but it says Protected Member is not accessible . Please point out where am i wrong?

You have to declare the state variables inside the constructor.
constructor(props) {
super(props);
this.showPicker = this.showPicker.bind(this);
this.state = {
imageSource : null,
}
}
Also the onPress{} method inside Button is empty, you need to call that showPicker() function inside onPress{}, if that's where you desire to call it.

Related

I cant able to send in image data to my server using RNFetchBlob in react native

I am making a image upload page. i used 2 library 1.react-native-image-picker and rn-fetch-blob. when i perform a script it's show an error like
"RNFetchBlob failed to create request multipart body :Value for data cannot be cast from ReadableNativeMap to String"
And
"Attempt to invoke virtual method 'int java.io.InputStream.read(byte[], int, int)' on a null object reference"
i don't have an idea how to do that. i am new in react native so please help me to find what's problem are there and how to solve it.
here i am write my code. please find out the solution
import React, { Component from 'react';
import { StyleSheet, Text, View, PixelRatio, TouchableOpacity, Image, TextInput, Alert } from 'react-native';
import {launchCamera, launchImageLibrary} from 'react-native-image-picker';
import RNFetchBlob from 'rn-fetch-blob';
export default class UploadProfile extends Component {
constructor() {
super();
this.state = {
ImageSource: null,
data: null,
Image_TAG: ''
}
}
selectPhotoTapped() {
const options = {
quality: 1.0,
maxWidth: 500,
maxHeight: 500,
storageOptions: {
skipBackup: true
}
};
launchImageLibrary(options, (response) => {
console.log('Response = ', response);
if (response.didCancel) {
console.log('User cancelled photo picker');
}
else if (response.error) {
console.log('ImagePicker Error: ', response.error);
}
else if (response.customButton) {
console.log('User tapped custom button: ', response.customButton);
}
else {
let source = { uri: response.assets[0].uri };
const data = new FormData();
data.append('photo', {
name: response.assets[0].fileName,
type: response.assets[0].type,
uri: response.assets[0].uri,
});
this.setState({
ImageSource: source,
data: data,
});
}
});
}
uploadImageToServer = () => {
RNFetchBlob.fetch('POST', 'https://demo.com/api/pro_upload.php', {
Authorization: "Bearer access-token",
otherHeader: "foo",
'Content-Type': 'multipart/form-data',
}, [
{ name: 'image', filename: 'image.png', type: 'image/png', data: this.state.data },
{ name: 'image_tag', data: this.state.Image_TAG }
]).then((resp) => {
var tempMSG = resp.data;
tempMSG = tempMSG.replace(/^"|"$/g, '');
Alert.alert(tempMSG);
}).catch((err) => {
// ...
})
}
render() {
return (
<View style={styles.container}>
<TouchableOpacity onPress={this.selectPhotoTapped.bind(this)}>
<View style={styles.ImageContainer}>
{this.state.ImageSource === null ? <Text>Select a Photo</Text> :
<Image style={styles.ImageContainer} source={this.state.ImageSource} />
}
</View>
</TouchableOpacity>
<TextInput
placeholder="Enter Image Name "
onChangeText={data => this.setState({ Image_TAG: data })}
underlineColorAndroid='transparent'
style={styles.TextInputStyle}
/>
<TouchableOpacity onPress={this.uploadImageToServer} activeOpacity={0.6} style={styles.button} >
<Text style={styles.TextStyle}> UPLOAD IMAGE TO SERVER </Text>
</TouchableOpacity>
</View>
);
}
}
I want to upload an image to server and store this image using php

TypeError: undefined is not an object (evaluating '_reactNativeImagePicker.default.showImagePicker')

Using React Image Picker i am facing this error:
TypeError: undefined is not an object (evaluating '_reactNativeImagePicker.default.showImagePicker')
This is what happens when i click on image picker function
Mobile Screenshot:
This is my Code:
import React from 'react';
import { View, Text,Button } from 'react-native';
import ImagePicker from 'react-native-image-picker';
const options = {
title: 'Select Avatar',
customButtons: [{ name: 'fb', title: 'Choose Photo from Facebook' }],
storageOptions: {
skipBackup: true,
path: 'images',
},
};
function Picker(){
const openPicker =()=>{
ImagePicker.showImagePicker(options, (response) => {
console.log('Response = ', response);
if (response.didCancel) {
console.log('User cancelled image picker');
} else if (response.error) {
console.log('ImagePicker Error: ', response.error);
} else if (response.customButton) {
console.log('User tapped custom button: ', response.customButton);
} else {
const source = { uri: response.uri };
// You can also display the image using data:
// const source = { uri: 'data:image/jpeg;base64,' + response.data };
console.log(source)
}
});
}
return(
<View>
<Button onPress={openPicker} title="Open image picker"></Button>
</View>
)
}
export default Picker;
I had this same issue and this is how I solved it.
import * as ImagePicker from "react-native-image-picker"
If your react-native-image-picker version is 3.x.x then, replace the above code with these lines,
import {launchCamera, launchImageLibrary} from 'react-native-image-picker'; // Migration from 2.x.x to 3.x.x => showImagePicker API is removed.
...
const openPicker =()=>{
launchCamera(options, (response) => { // Use launchImageLibrary to open image gallery
console.log('Response = ', response);
if (response.didCancel) {
console.log('User cancelled image picker');
} else if (response.error) {
console.log('ImagePicker Error: ', response.error);
} else if (response.customButton) {
console.log('User tapped custom button: ', response.customButton);
} else {
const source = { uri: response.uri };
// You can also display the image using data:
// const source = { uri: 'data:image/jpeg;base64,' + response.data };
console.log(source)
}
});
Read the docs
Issue:
import ImagePicker from "react-native-image-picker"
Solution:
import * as ImagePicker from "react-native-image-picker"
check your lib version if its 3x then try something like this
import * as ImagePicker from "react-native-image-picker"
<Button onPress={() =>
ImagePicker.launchImageLibrary(
{
mediaType: 'photo',
includeBase64: false,
maxHeight: 200,
maxWidth: 200,
},
(response) => {
console.log(response);
this.setState({resourcePath: response});
},
)
}
title="Select Image"/>
Replace
import { ImagePicker } from 'react-native-image-picker',
with
var ImagePicker = require('react-native-image-picker');
This is working for me.
you can downgrade your version of the image picker library I am facing same issue then I am using this CLI command to downgrade a version of the image picker
npm install react-native-image-picker#2.3.4
same like you can use this command
showImagePicker API is removed.
use Direct launchCamera or launchImageLibrary
import {launchCamera, launchImageLibrary} from 'react-native-image-picker';

How to pass api data from react native to html and vice-versa in react-native-html-to-pdf

i am using react-native-html-to-pdf package to create a pdf file i want to pass the api response from react-native to html and receive the data from html. the options available for this npm package is very minimum
There is no options in the package so that i can use it, can someone help me with this ?
Below is my code.
import React, { Component } from 'react';
import { Text, TouchableOpacity, View, StyleSheet, Image, PermissionsAndroid, Platform,} from 'react-native';
import RNHTMLtoPDF from 'react-native-html-to-pdf';
import htmlContent from './htmlContent'
export default class App extends Component {
constructor(props) {
super(props)
this.state = {
apiData: [],
filePath: ''
}
}
askPermission() {
var that = this;
async function requestExternalWritePermission() {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
{
title: 'External Storage Write Permission',
message:
'App needs access to Storage data in your SD Card ',
}
);
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
that.createPDF();
} else {
alert('WRITE_EXTERNAL_STORAGE permission denied');
}
} catch (err) {
alert('Write permission err', err);
console.warn(err);
}
}
if (Platform.OS === 'android') {
requestExternalWritePermission();
} else {
this.createPDF();
}
}
componentDidMount(){
fetch(`http://API`)
.then((response) => response.json())
.then((responseJson) => {
**console.log("DATA", responseJson) // NEED TO SEND THIS DATA TO "HTML"**
this.setState(() => ({
apiData: responseJson
}))
})
}
async createPDF() {
let options = {
html:htmlContent, // API DATA SHOULD BE SENT TO HTML
fileName: 'RTT Report',
directory: 'docs',
width: 800,
};
let file = await RNHTMLtoPDF.convert(options);
console.log(file.filePath);
this.setState({filePath:file.filePath});
}
render() {
return (
<View style={styles.MainContainer}>
<TouchableOpacity onPress={this.askPermission.bind(this)}>
<View>
<Image
//We are showing the Image from online
source={{
uri:
'https://raw.githubusercontent.com/AboutReact/sampleresource/master/pdf.png',
}}
//You can also show the image from you project directory like below
//source={require('./Images/facebook.png')}
style={styles.ImageStyle}
/>
<Text style={styles.text}>Create PDF</Text>
</View>
</TouchableOpacity>
<Text style={styles.text}>{this.state.filePath}</Text>
</View>
);
}
}
In createPDF method :
// html:htmlContent, // API DATA SHOULD BE SENT TO HTML
html: this.state.apiData // <-- you have stored your html in the state
EDIT:
Probably I was too fast answering, now I think I got your point , here you have an example :
// html: '<h1>PDF TEST</h1>', <-- example from react-native-html-to-pdf
const exampleData = [
{
title: "Element title",
content: "Element content"
},
{
title: "Other title",
content: "Other element content"
}
]
function generateHTML () {
const data = exampleData
// const data = this.state.apiData // <-- in your case
let htmlContent = '<html><body>'
htmlContent += data.map(entry => {
return `<h5>${entry.title}</h5> <br /> <p>${entry.content}</p>`
}).join(' ')
htmlContent += '</body></html>'
return htmlContent
}

How to call a function directly in a Component in React Native

I made a CameraComponent.js having function launchCamera(). I am calling CameraComponent.js in my BottamTab navigation. I had make simple button to launch camera by calling launchCamera(). But i want to launch camera directly when component call in BottamTab navigation just like in whatsapp moving topTab to left. I tried to call function in constructor instead of ComponentWillMount(as it is removed in react native). But nothing work. Here is my below code
export default class CameraComponent extends React.Component {
constructor(props) {
super(props);
launchCamera();
this.state = {
filePath: {},
};
}
launchCamera = () => {
let options = {
storageOptions: {
skipBackup: true,
path: 'images',
},
};
ImagePicker.launchCamera(options, response => {
// console.log('Response = ', response);
if (response.didCancel) {
console.log('User cancelled image picker');
} else if (response.error) {
console.log('ImagePicker Error: ', response.error);
} else {
let source = response;
// You can also display the image using data:
// let source = { uri: 'data:image/jpeg;base64,' + response.data };
this.setState({
filePath: source,
});
}
});
};
render() {
return (
<View style={styles.container}>
<TouchableOpacity onPress={this.launchCamera.bind(this)} >
<Text>Launch Camera</Text>
</TouchableOpacity>
</View>
);
}
}

How to open a pdf from my flatlist in react-native?

Im trying to pick a file (pdf-file) from a module called react-native-file-picker. This works ok, and gaves me name, type, path and uri.
After this, i display the name of the document that i picked in a flatlist.
Now, what i want is to "onPress" of the item in the flatlist, open the document with some pdf viewer or something like that.
I've already tried to use other modules like react-native-view-pdf and react-native-pdf and react-native-pdf-view but i cant access the state of my uri with either of them.
The last one that i used it was react-native-file-viewer and doesn't work very well because it doesn't open the item on press.
This is my actual code.
import React from 'react';
import { StyleSheet, Text, View, TouchableOpacity, Button, TextInput,
Dimensions, FlatList } from 'react-native';
import AsyncStorage from '#react-native-community/async-storage'
import FilePickerManager from 'react-native-file-picker';
import FileViewer from 'react-native-file-viewer';
global.myfunction = function myfunction() {
FilePickerManager.showFilePicker(null, (response) => {
console.log('Response = ', response);
if (response.didCancel) {
console.log('User cancelled file picker');
}
else if (response.error) {
console.log('FilePickerManager Error: ', response.error);
}
else {
this.storeItem(response)
}
});
};
export default class Docs extends React.Component {
static navigationOptions = ({ navigation }) => {
return {
title: 'Docs',
header: null
}
};
state = {
arr: [],
local: '',
password: '',
obj: null,
count: 1,
image: {},
b64: '',
isModalVisible: false,
pdfuri: null,
};
pdf = () => {
FilePickerManager.showFilePicker(null, (response) => {
console.log('Response = ', response);
if (response.didCancel) {
console.log('User cancelled file picker');
}
else if (response.error) {
console.log('FilePickerManager Error: ', response.error);
}
else {
this.storeItem(response)
this.setState({
pdfuri: response.path
});
}
});
}
toggleModal = (item) => {
this.setState({ isModalVisible: !this.state.isModalVisible, obj: item });
};
storeItem(item) {
try {
//we want to wait for the Promise returned by AsyncStorage.setItem()
//to be resolved to the actual value before returning the value~
console.log(item)
var joined = this.state.arr.concat(item);
console.log('files ', joined)
this.setState({ arr: joined })
AsyncStorage.setItem('files', JSON.stringify(joined));
console.log(this.state.arr)
} catch (error) {
console.log(error.message);
}
}
componentDidMount() {
//Here is the Trick
const { navigation } = this.props;
}
componentWillMount() {
AsyncStorage.getItem('files').then(array => {
item = JSON.parse(array)
item ? this.setState({ arr: item }) : null;
console.log(this.state.arr)
})
}
verpdf() {
const path =
"content://com.android.providers.downloads.documents/document/4183"
FileViewer.open(path, { showOpenWithDialog: true })
.then(() => {
// success
})
.catch(error => {
// error
});
}
render() {
return (
<View style={[styles.container, { marginTop: 20 }]}>
<FlatList
data={this.state.arr}
renderItem={({ item }) => <TouchableOpacity onPress=
{this.verpdf(item)} style={{ marginBottom: 10, marginTop: 10, alignItems: 'center' }}>
<Text>{item.fileName}</Text></TouchableOpacity>}
/>
<Button title='ok' onPress={this.pdf}></Button>
</View>
);
}
}
How should i do this?
Try to change the event handler from
onPress=
{this.verpdf(item)}
to
onPress=
{()=>this.verpdf(item)}
Like #Oleg said, to open a certain item i needed to change the event handler to a arrow function.
onPress = {this.verpdf(item)}
to
onPress= {()=>this.verpdf(item)}
After that i wanted to open a certain item from my flatlist which i did:
verpdf(item) {
const path = item.path
FileViewer.open(path, { showOpenWithDialog: true })
.then(() => {
// success
})
.catch(error => {
// error
});
}