Possible Unhandled Promise Rejection (id: 0): TypeError: undefined is not an object (evaluating '_this.props.navigation.navigate') - react-native

I'm trying to display an image I have captured using expo-camera, from the camera component I'm trying to navigate to a new file which will display the image but after I took the image it won't navigate to the new page.
I tried importing the file and then navigate it but it still won't work and give me the warning instead.
This is the code where I tried to navigate to the new file.
export default class CameraExample extends React.Component {
state = {
hasCameraPermission: null,
type: Camera.Constants.Type.back,
};
async componentDidMount() {
const { status } = await Permissions.askAsync(Permissions.CAMERA);
this.setState({ hasCameraPermission: status === 'granted' });
}
snap = async() => {
if(this.camera) {
console.log('Taking photo');
const options = {quality: 1, base64: true, fixOrientation: true, exif: true};
const photo = await this.camera.takePictureAsync(options);
this.props.navigation.navigate("Show", {photouri: photo.uri})
}
}
render() {
const { hasCameraPermission } = this.state;
if (hasCameraPermission === null) {
return <View />;
} else if (hasCameraPermission === false) {
return <Text>No access to camera</Text>;
} else {
return (
<View style={{ flex: 1 }}>
<Camera style={{ flex: 1 }} type={this.state.type}
ref = {ref => {
this.camera = ref;
}}
>
<View
style={{
flex: 1,
backgroundColor: 'transparent',
flexDirection: 'row',
}}>
<TouchableOpacity onPress={this.snap.bind(this)}>
<Ionicons
name = "md-camera"
color = "white"
size = {30}
/>
</TouchableOpacity>
<TouchableOpacity
style={{
flex: 0.1,
alignSelf: 'flex-end',
alignItems: 'center',
}}
onPress={() => {
this.setState({
type:
this.state.type === Camera.Constants.Type.back
? Camera.Constants.Type.front
: Camera.Constants.Type.back,
});
}}>
<Ionicons
name = "md-reverse-camera"
color = "white"
size = {30}
/>
</TouchableOpacity>
</View>
</Camera>
</View>
);
}
}
}
And this is the code where I try to display the image.
export default class ShowImages extends React.Component{
render(){
console.log('OK')
const { navigation } = this.props;
const paramm = navigation.getParam('photouri');
return(
<Content>
<View>
<Text>
paramm: {JSON.stringify(paramm)}
</Text>
<Image style={{height: 700, width: 850, alignSelf: "center"}}
source={{uri: this.props.navigation.state.paramm.photouri}}
resizeMode="contain"/>
</View>
</Content>
)
}
}
I expect it to navigate to the new page and display the captured
image but it gave me the warning. I can't seem to find what is wrong with my code. Can anyone suggest what I should do? Thank you.

change this
<TouchableOpacity onPress={this.snap.bind(this)}> => <TouchableOpacity onPress={this.snap}>
Put it in the status value and pass it on.
export default class ShowImages extends React.Component{
constructor(props) {
super(props);
this.state = {
paramm: this.props.navigation.state.params.photouri
};
}
...
<Image style={{height: 700, width: 850, alignSelf: "center"}}
source={{uri: this.state.paramm }}
resizeMode="contain"/>

Related

React native WARN Possible Unhandled Promise Rejection (id: 2): Error: [AsyncStorage] Passing null/undefined as value is not supported

In react native cli i was trying to login but not working nd same thing working fine in expo nd this error is showing please let me know what can i do to do this???? i have added the action ,reducer,component page
getting error this //
WARN Possible Unhandled Promise Rejection (id: 2):
Error: [AsyncStorage] Passing null/undefined as value is not supported. If you want to remove value, Use .removeItem method instead.
Passed value: undefined
Passed key: userToken
checkValidInput#http://localhost:8081/index.bundle?platform=android&dev=true&minify=false&app=com.easylab&modulesOnly=false&runModule=true:146791:24
http://localhost:8081/index.bundle?platform=android&dev=true&minify=false&app=com.easylab&modulesOnly=false&runModule=true:146835:24..........................
my action is like this // actions>index.js page
export const login = (formValues, actions) => {
return async dispatch => {
dispatch(startSubmitting());
const url = `/auth/login`;
var formdata = new FormData();
formdata.append('email', formValues.email);
formdata.append('password', formValues.password);
const response = await api
.post(url, formdata)
.then(res => {
return res;
})
.catch(error => {
actions.setErrors(error.response.data.error);
return error.response;
});
dispatch({
type: 'LOGIN',
payload: response,
});
dispatch(stopSubmitting());
await AsyncStorage.setItem('userToken', response.data.access_token);
};
};
//my component page login.js
import { StatusBar } from "expo-status-bar";
import React, { useState, useEffect } from "react";
import {
Field,
Form,
Formik,
FormikProps,
ErrorMessage,
useFormik,
} from "formik";
import { connect } from "react-redux";
import { login } from "../../../actions";
import { Button } from "react-native-paper";
import ErrorMsg from "./ErrorMsg";
class Login extends React.Component {
submitLogin = (values, actions) => {
this.props.login(values, actions);
};
render() {
const { onChangeText, text, navigation } = this.props;
const { isSubmitting ,isLoading} = this.props.commonData;
const { login, loginLoading, isLoggedIn } = this.props.loginForm;
{
login && this.props.navigation.navigate("Nav1");
}
return (
<KeyboardAvoidingView
behavior={Platform.OS === "ios" ? "padding" : "height"}
style={styles.container}
>
{/* {verifyOtp ? <Loader loading={verifyOtp} /> : null} */}
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
<View style={styles.inner}>
<View style={{ alignItems: "center" }}>
<Image
source={require("../../../assets/images/diabetes-awareness-month-1440x810.jpg")}
style={{
height: 110,
// top: -20,
resizeMode: "contain",
}}
/>
</View>
<View style={{}}>
<Text onPress={() => this.props.navigation.navigate("Register")}>
New User ? Register
</Text>
</View>
<View style={{}}>
<Text style={{ fontSize: 24, fontWeight: "bold" }}>LOGIN</Text>
</View>
<View style={{}}>
<Formik
initialValues={{
email: "",
password: "",
}}
validate={(values) => {
const error = {};
if (!values.password) {
error.password = (
<Text style={{ color: "red", fontSize: 10 }}>
Password Required
</Text>
);
}
if (!values.email) {
error.email = (
<Text style={{ color: "red", fontSize: 10 }}>
Email Type Required
</Text>
);
}
return error;
}}
onSubmit={(values, actions) => {
this.submitLogin(values, actions);
}}
enableReinitialize={true}
>
{(props: FormikProps<any>) => (
<>
<View style={{ paddingBottom: 10 }}>
<Text>Login To Check Your Account</Text>
</View>
<View>
{/* email */}
<View style={{ marginBottom: 20 }}>
<View style={styles.textInputContainer}>
<MaterialCommunityIcons
style={{ alignSelf: "center", paddingLeft: 10 }}
name="email"
size={28}
/>
<TextInput
style={styles.input}
onChangeText={props.handleChange("email")}
value={props.values.email}
autoFocus={true}
placeholder="Email"
/>
</View>
</View>
<View style={{ marginBottom: 20 }}>
<View style={styles.textInputContainer}>
<MaterialCommunityIcons
style={{ alignSelf: "center", paddingLeft: 10 }}
name="security"
size={28}
/>
<TextInput
style={styles.input}
onChangeText={props.handleChange("password")}
maxLength={10}
secureTextEntry={true}
value={props.values.password}
placeholder="Password"
/>
</View>
</View>
{/* {props.touched.password && props.errors.password && ( */}
<ErrorMsg msg={props.errors.password} />
{/* )} */}
<TouchableHighlight
underlayColor="white"
onPress={props.handleSubmit}
>
<Text color="white" style={styles.buttonStyle}>
{/* {isSubmitting ? (
<ActivityIndicator
size="small"
color="#4DB2F8"
/>
) : ( */}
<Text>LOGIN </Text>
{/* )} */}
</Text>
</TouchableHighlight>
</View>
</>
)}
</Formik>
</View>
</View>
</TouchableWithoutFeedback>
</KeyboardAvoidingView>
);
}
}
const mapStateToProps = (state) => {
return {
loginForm: state.loginData,
commonData: state.commonFunctions,
};
};
export default connect(mapStateToProps, { login })(Login);
and in redux trying to store like this// reducers>index.js page
const loginReducer = (
state = {
otp: false,
mobile: null,
login: false,
loginLoading: true,
verifyOtp: false,
isLoggedIn: false,
},
action
) => {
switch (action.type) {
case "LOGIN": {
if (action.payload.status === 200) {
let newState = { ...state, login: true, isLoggedIn: true };
return newState;
} else {
let newState = { ...state, login: false, isLoggedIn: false };
return newState;
}
}
default:
return state;
}
};
export default combineReducers({
loginData: loginReducer,
});
Your problem is that you are trying to set userToken to null on this line:
await AsyncStorage.setItem('userToken', response.data.access_token);
You need to do a null check before setting the token, since Async Storage does not support setting null values. Try:
if (response && response.data && response.data.access_token) {
await AsyncStorage.setItem('userToken', response.data.access_token);
}

Render conditionally header in react native

Hi I'm trying to render the header based on a state. If the state is equals to true I'm showing an avatar image and if it's false I'm rendering a default logo. I've tried doing this based on a ternary operator but it's not working. Here is the code :
static navigationOptions = ({navigation}) => {
const { params } = navigation.state;
return {
headerTitle: () => (
<View style ={{alignItems: 'center', justifyContent: 'center',flex:1, flexDirection:'column', overflow:'visible'}}>
{this.state.Loaded == false ?
<View style ={{alignItems: 'center', justifyContent: 'center',flex:1, flexDirection:'column', overflow:'visible'}}>
<Text style={{marginBottom:15,fontSize:20,fontWeight:"900", color:'#000' }}>Pseudo</Text>
<Image
style = {styles.avatar}
source = {require('../../../Assets/avatar.jpg')} />
</View>
:
<View style={[styles.bandeauHeader, { } ]}>
<Text style={styles.textHeader}>Aide</Text>
<Image source={GlobalInclude.LogoIconRose} style={styles.logoBandeauHeader} />
</View>
}
</View>
)
};
};
You should consider updating the Navigation to newer version.
First the state is not available inside the static function so you will have to use the navigation params to update the header.
The code should be something like below which you can adopt in your solution.
class DetailsScreen extends React.Component {
state = {
flag: true,
};
static navigationOptions = ({ navigation }) => {
return {
headerTitle: navigation.getParam('flag') ? (
<Text>12323231321</Text>
) : (
<Text>67676777</Text>
),
};
};
render() {
const { navigation } = this.props;
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Details Screen</Text>
<Button
title="Update the title"
onPress={() =>
this.setState({ flag: !this.state.flag }, () =>
this.props.navigation.setParams({ flag: this.state.flag })
)
}
/>
</View>
);
}
}

How do I upload an image taken React-Native-camera to Firebase storage?

I want upload image taken with react-native-camera to https://github.com/invertase/react-native-firebase storage on RN
I can't upload image.
I tried image-picker-library and did work.
import React, { Component } from 'react';
import {Image, View, Text, StyleSheet, Dimensions,TouchableOpacity} from 'react-native'
import { RNCamera } from 'react-native-camera';
import {strings} from '../Lang/Strings';
import { Actions } from 'react-native-router-flux';
const { width, height } = Dimensions.get('window');
export default class ScanPage extends Component {
constructor(props) {
super(props);
this.state = {
takePicture = async () => {
if (this.camera) {
const options = { quality: 0.5, base64: true }
const data = await this.camera.takePictureAsync(options)
Actions.ProfilePage({imagePath:data.uri,
selectedIndex:this.state.selectedIndex,
shapes:this.state.shapes });
this.uploadPhoto(data);
};
};
render() {
const {selectedIndex, images, shapes} = this.state;
return(
<View style={styles.container}>
<RNCamera
ref={ref => {
this.camera = ref;
}}
style={styles.preview}
type={RNCamera.Constants.Type.front}
permissionDialogTitle={'Permission to use camera'}
permissionDialogMessage={'We need your permission to use your camera phone'} />
<View style={{flex:1,justifyContent:'center' ,alignItems:'center'}}>
<View style={{marginTop:120}}>
<Image source={images[selectedIndex]} >
</Image>
</View>
</View>
<View style={styles.buttonSection}>
<TouchableOpacity onPress={this._TogglePrev}>
<View style={styles.buttons}>
<Text style={{textAlign:'center',color: 'white'}}>
{strings.back}
</Text>
</View>
</TouchableOpacity>
<View style={{alignItems:'center', justifyContent:'center',
height:height*0.04}}>
<Text style ={{color:'white',textAlign:'center'}}>{shapes[selectedIndex]} </Text>
</View>
<TouchableOpacity onPress={this._ToggleNext}>
<View style={styles.buttons}>
<Text style={{textAlign:'center', color: 'white'}}>
{strings.next}
</Text>
</View>
</TouchableOpacity>
</View>
<View style={{alignItems:'center', justifyContent:'center',
backgroundColor:'#D9E6FF',height:height*0.001,width:width*1}}>
<Text style ={{color:'white',textAlign:'center'}}> </Text>
</View>
<View style={{ flex: 0, flexDirection: 'row', justifyContent: 'center'}}>
<TouchableOpacity onPress={this.takePicture.bind(this)} style={styles.capture}
>
<View style={{
backgroundColor: 'white',
borderRadius: (height*0.16)/2,
padding: 15,
alignSelf: 'center',
margin: 25,
height:height*0.085,
width:width*0.16,
justifyContent:'center',
alignItems:'center',
borderWidth:0.9,
borderColor:'#D9E6FF',}}></View>
</TouchableOpacity>
</View>
</View>
);
}
takePicture = async function() {
if (this.camera) {
const options = { quality: 0.5, base64: true };
const data = await this.camera.takePictureAsync(options);
Actions.ProfilePage({imagePath:data.uri,
selectedIndex:this.state.selectedIndex,
shapes:this.state.shapes
});
}
};
}
I didn't upload firebase,
versions
react: 16.4.1,
react-native: 0.56.0,
react-native-camera:1.12.0,
react-native-firebase:5.2.3
react-native-router-flux:4.0.1
Can't believe I've figured it out >.<
if you've set up your project correctly to include firebase
takePicture = async() => {
if (this.camera) {
// this code takes the picture
const options = { quality: 0.5, base64: true };
const data = await this.camera.takePictureAsync(options);
// open debug to see the uri of image
console.log(data.uri);
// send your data.uri off to firebase! :D
const processed = await firebase.vision().imageLabelerProcessImage(data.uri, {
confidenceThreshold: 0.8,
});
//Look at your debugger again
console.log('Label: ', processed);
}
};
I hope this helps!
_publish = async () => {
const imageuri= this.state.imagePath;
//this is where + how you want your image to be stored into
const refFile= firebase.storage().ref().child('profile_pic');
refFile.putFile(imageuri)
.catch(error => {
console.log(error);
// Alert.alert('Hey', error);
});
}
hope it helps!

GS1 barcode scanner reader in react native app

i used a barcode scanner expo library in my react native app but it's not able to scan the GS1 type barcode so which library i used in my app?
Do you mean which library you should use ? If its that and you are not using expo, then https://github.com/react-native-community/react-native-camera this is pretty good and easy to go dependency which you can use to serve your purpose.
class BarScannerView extends Component {
constructor(props) {
super(props);
this.camera = null;
this.barcodeCodes = [];
this.state = {
changeScreen: false,
camera: {
type: RNCamera.Constants.Type.back,
flashMode: RNCamera.Constants.FlashMode.auto,
barcodeFinderVisible: true
}
};
}
onBarCodeRead = (scanResult) => {
if (scanResult.data !== null) {
let bacodeScanResult = scanResult.data
AsyncStorage.setItem('barcodeValue', bacodeScanResult)
return this.props.navigation.navigate('Stock')
}
return;
}
componentDidMount() {
console.log('componentDidMount', this.props)
this.props.navigation.dismiss()
}
componentWillUnmount() {
console.log('componentWillUnmount', this.props)
}
render() {
return (
<View style={styles.container}>
<RNCamera
ref={ref => {
this.camera = ref;
}}
barcodeFinderVisible={this.state.camera.barcodeFinderVisible}
barcodeFinderWidth={280}
barcodeFinderHeight={220}
barcodeFinderBorderColor="white"
barcodeFinderBorderWidth={2}
defaultTouchToFocus
flashMode={this.state.camera.flashMode}
onBarCodeRead={this.onBarCodeRead}
onFocusChanged={() => {}}
onZoomChanged={() => {}}
permissionDialogTitle={'Permission to use camera'}
permissionDialogMessage={'We need your permission to use your camera phone'}
style={styles.preview}
type={this.state.camera.type}
/>
<View style={[styles.overlay, styles.topOverlay]}>
<Text style={styles.scanScreenMessage}>Please scan the barcode.</Text>
</View>
<View style={{position: 'absolute', top: 150, left: '12%' }}>
<View
style={{
width: 300,
height: 300,
backgroundColor: 'transparent',
borderColor: 'white',
borderWidth: 1
}}
>
</View>
</View>
<View style={[styles.overlay, styles.bottomOverlay]}>
<Button
onPress={() => { console.log('scan clicked'); }}
style={styles.enterBarcodeManualButton}
title="Choose Barcode"
/>
</View>
</View>
);
}
}
You can follow this.

Expo React Native TakeSnapShot Async Returning Black Screen

I'm new to React Native and am trying to create an app that will use Expo's Camera and Takesnapshot Async to take a picture and save it to Cameraroll.
I'm probably doing something really dumb, but right now (even though the view is showing the camera before I press the snapshot button), my code is saving a black image when I click the button instead of the image captured by the camera to the camera roll.
Here is my code for the CameraScreen (I'm using code from https://docs.expo.io/versions/latest/sdk/camera to open the camera and code from https://snack.expo.io/SJRvlSxvb to save a snapshot):
class CameraScreen extends React.Component {
state = {
hasCameraPermission: null,
type: Camera.Constants.Type.back,
cameraRollUri: null,
};
async componentWillMount() {
const { status } = await Permissions.askAsync(Permissions.CAMERA);
this.setState({ hasCameraPermission: status === 'granted' });
}
render() {
const { hasCameraPermission } = this.state;
if (hasCameraPermission === null) {
return <View />;
} else if (hasCameraPermission === false) {
return <Text>No access to camera</Text>;
} else {
return (
<View style={{ flex: 1 }} >
<Camera style={{ flex: 1 }}
type={this.state.type}
collapsable={false}
ref={view => {
this._container = view;
}} >
<View
style={{
flex: 1,
backgroundColor: 'transparent',
flexDirection: 'row',
}} >
{this.state.cameraRollUri &&
<Image
source={{ uri: this.state.cameraRollUri }}
style={{ width: 200, height: 200 }
}
/>}
<TouchableOpacity style={styles.gridItem} onPress={this._saveToCameraRollAsync}>
</TouchableOpacity>
<TouchableOpacity
style={{
flex: 0.1,
alignSelf: 'flex-end',
alignItems: 'center',
}}
onPress={() => {
this.setState({
type: this.state.type === Camera.Constants.Type.back
? Camera.Constants.Type.front
: Camera.Constants.Type.back,
});
}}>
<Text
style={{ fontSize: 18, marginBottom: 10, color: 'white' }}>
{' '}Flip{' '}
</Text>
</TouchableOpacity>
</View>
</Camera>
</View>
);
}
}
_saveToCameraRollAsync = async () => {
let result = await takeSnapshotAsync(this._container, {
format: 'png',
result: 'file',
});
let saveResult = await CameraRoll.saveToCameraRoll(result, 'photo');
this.setState({ cameraRollUri: saveResult });
};
}
I first thought that the view saved to this._components wasn't the right view, but I tried attaching the code
ref={view => {
this._container = view;
}
to different views in the class but nothing seems to be changing.
Thanks in advance for any help - I've been struggling for this for a pretty long time now :(
PS: This is my first stack overflow post; I apologize in advance if there anything wrong with my post.
Expo Camera doesn’t support snapshot instead you can use the method takePictureAsync from Camera which return an image object.
const image = await this._container.takePictureAsync();
Camera component from Expo doesn't support takeSnapshotAsync.
Otherwise if you are using any Expo-pixi component, this code can be helpful:
const { uri } = await this.sketch.takeSnapshotAsync();
//save sketch/signature/doodles in DCIM folder.
let saveResult = await CameraRoll.saveToCameraRoll(uri, 'photo');