React Native: State changed, component doesnt re-render - react-native

After image is selected through Image Picker the button which opens the picker has to be replaced by the Image. I am doing that in the following manner
{ this.state.userImage === null ?
<IconButton
icon={{name: "photo-camera", size: 32}}
buttonStyle={{backgroundColor: "#397af8", borderRadius: 2,marginLeft: 50,height: 50, width: 200}}
textStyle={{textAlign: 'center',color: "#000000"}}
title={this.state.textBttn}
onPress={() => this._selectImage()}/> : <Image style={styles.userimg} source={this.state.userImage} />
}
Am able to confirm that the userImage changes after an image is selected but the component doesn't re render. Any solutions please?
Edit : updating the state
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 {
let source = { uri: response.uri };
// let source = { uri: 'data:image/jpeg;base64,' + response.data };
this.setState({
userImage: source,
testVal : 'changed'
});
console.log("state = "+this.state.userImage);
console.log("state = "+this.state.testVal);
}
});

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

how to Scan qr code after capturing an image in react native

I am making a qr code scanner, where user can upload a qr code image from gallery and from that we can get the data of qr code.
Below is my code:
import RNQRGenerator from 'rn-qr-generator';
import {launchImageLibrary} from 'react-native-image-picker';
const options = {
title: 'photoUpload',
takePhotoButtonTitle: 'photoTake',
chooseFromLibraryButtonTitle: 'photoLibrary',
cancelButtonTitle: 'cancel',
quality: 0.7,
base64: true,
maxWidth: 728,
};
const App = () => {
const onPick = () => {
launchImageLibrary(options, 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 {
RNQRGenerator.detect({uri: response.assets[0].uri})
.then(res => {
console.log('Detected value', res);
if (res.values.length === 0) {
console.log('Code not found');
} else {
console.log('value: ', res.values);
}
})
.catch(err => {
console.log('Cannot detect', err);
});
}
});
};
return (
<Button
title="Pick from library"
onPress={() => {
onPick();
}}
/>
);
};
This is working fine if user has the actual qr code image
I have an edge case: if user clicks an image of qr code, and then upload this image from gallery.
For this edge case, my written code is not working. I am not sure how to solve this edge case issue.
Try this
import RNQRGenerator from 'rn-qr-generator';
RNQRGenerator.detect({
uri: PATH_TO_IMAGE, // local path of the image. Can be skipped if base64 is passed.
base64: imageBase64String, // If uri is passed this option will be skipped.
})
.then(response => {
const { values } = response; // Array of detected QR code values. Empty if nothing found.
})
.catch(error => console.log('Cannot detect QR code in image', error));
To scan the image and get the information about that image barcode and qrcode...
you have to install npm i rn-qr-generator and to choose the image you have to install npm i react-native-image-picker
example:-
import {launchImageLibrary} from 'react-native-image-picker';
import RNQRGenerator from 'rn-qr-generator';
const openlibrary=async()=>{
const galleryOptions = {
mediaType: 'photo',
includeBase64: true,
};
launchImageLibrary(galleryOptions,(res)=>{
if(res.didCancel){
console.error("cancelled")
}else{
RNQRGenerator.detect({
base64:res?.assets[0]?.base64
}).then((item)=>{
console.log(item)
}).catch((err)=>{
console.log(err)
})
}
console.log(res)
}).catch(err=>{
console.log("err",err)
})
}

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
});
}

Hookin' Images from phone storage with React-Hooks

The RNImage Picker says: 'Then later, if you want to display this image in your render() method:' But it's a default function. How can I display the image on screen?
export default function Expenses(){
const [ imageSource, setImageSource ] = useState(null);
const [ data, setData ] = useState(null);
uploadImage = async () => {
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 };
setImageSource({
imageSource: source
});
}
})
};
I'm using Styled-components and Photo it's styled.Image.
return (
<Container>
<Photo source={imageSource} />
<ButtonTouch
onPress={uploadImage}>
<TextButton>Select Image</TextButton>
</ButtonTouch>
</Container>
);
}
And let me simplify for yall. I'm trying get this photo on my phone storage or take a photo, whatever and display this photo on screen. But I can't display that. Return nothing.