TypeError: null is not an object (evaluating ''this.state.torchon') - javascript

I don't know what am doing wrong in the code below...I want to toggle flash light on/off during camera capturing, but my code is not working, I tried binding the state in different ways but is still not working for me...Below is my code. Please I need help on how to get this working.
import React, { Component } from 'react';
import { View, StyleSheet, Text, TouchableOpacity } from 'react-native';
import { RNCamera } from 'react-native-camera';
import RNFetchBlob from 'rn-fetch-blob';
import Icon from 'react-native-vector-icons/Ionicons';
class cameraComponent extends Component {
toggleTorch()
{
let tstate = this.state.torchon;
if (tstate == RNCamera.Constants.FlashMode.off){
tstate = RNCamera.Constants.FlashMode.torch;
} else {
tstate = RNCamera.Constants.FlashMode.off;
}
this.setState({torchon:tstate})
}
takePicture = async () => {
if(this.camera) {
const options = { quality: 0.5, base64: true };
const data = await this.camera.takePictureAsync(options);
console.log(data.base64)
const path = `${RNFetchBlob.fs.dirs.CacheDir}/test.png`;
console.log('path', path)
try {
RNFetchBlob.fs.writeFile(path, data.base64, 'base64')
}
catch(error) {
console.log(error.message);
}
}
};
render() {
return (
<View style={styles.container}>
<RNCamera
ref = {ref=>{
this.camera=ref;
}}
style={styles.preview}
flashMode={this.state.torchon}
// type = {RNCamera.Constants.Type.back}
>
</RNCamera>
<View style={{ flex: 0, flexDirection: 'row', justifyContent: 'center' }}>
<TouchableOpacity onPress={this.takePicture.bind(this)} style={styles.captureBtn} />
</View>
<TouchableOpacity style={styles.toggleTorch} onPress={this.toggleTorch.bind(this)}>
{ this.state.torchon == RNCamera.Constants.FlashMode.off? (
<Image style={styles.iconbutton} source={require('../images/flashOff.png')} />
) : (
<Image style={styles.iconbutton} source={require('../images/flashOn.png')} />
)
}
</TouchableOpacity>
</View>
);
};
}
export default cameraComponent;

You have not initialized the state anywhere and when you access this.state.torchon it throws the error because this.state is null.
You have to initialize the state.
class cameraComponent extends Component {
this.state={ torchon:RNCamera.Constants.FlashMode.off };
toggleTorch=()=>
{
let tstate = this.state.torchon;
if (tstate == RNCamera.Constants.FlashMode.off){
tstate = RNCamera.Constants.FlashMode.torch;
} else {
tstate = RNCamera.Constants.FlashMode.off;
}
this.setState({torchon:tstate})
}
You can also initialize the state inside the constructor as well.

Related

How To Get Props in another Screen in react navigation?

I have an issue with react-navigation in passing the props to another screen,
I need to pass some props to Detail screen when the user presses one of the List Places I need to push screen with some details about the place like a Name of place and Image of place,
Errors :
this is my Code
Reducer
import { ADD_PLACE, DELETE_PLACE } from "../actions/actionTypes";
const initialState = {
places: []
};
import placeImage from "../../assets/img.jpg";
const reducer = (state = initialState, action) => {
switch (action.type) {
case ADD_PLACE:
return {
...state,
places: state.places.concat({
key: Math.random(),
name: action.placeName,
// image: placeImage,
image: {
uri:
"https://images.unsplash.com/photo-1530009078773-9bf8a2f270c6?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=750&q=80"
}
})
};
case DELETE_PLACE:
return {
...state,
places: state.places.filter(place => {
return place.key !== state.selectedPlace.key;
})
};
default:
return state;
}
};
export default reducer;
Place List Component
import React from "react";
import { FlatList, StyleSheet, ScrollView } from "react-native";
import ListItem from "../ListItem/ListItem";
const PlaceList = props => {
return (
<FlatList
style={styles.listContainer}
data={props.places}
renderItem={info => (
<ListItem
placeName={info.item.name}
placeImage={info.item.image}
onItemPressed={() => props.onItemSelected(info.item.key)}
/>
)}
keyExtractor={index => String(index)}
/>
);
};
export default PlaceList;
Find Place Screen
import React, { Component } from "react";
import { View, Text } from "react-native";
import { connect } from "react-redux";
import { StackActions } from "react-navigation";
import PlaceList from "../../Components/PlaceList/PlaceList";
class FindPlaceScreen extends Component {
constructor() {
super();
}
itemSelectedHandler = key => {
const selPlace = this.props.places.find(place => {
return place.key === key;
});
this.props.navigation.push("PlaceDetail", {
selectedPlace: selPlace,
name: selPlace.name,
image: selPlace.image
});
};
render() {
return (
<View>
<PlaceList
places={this.props.places}
onItemSelected={this.itemSelectedHandler}
/>
</View>
);
}
}
const mapStateToProps = state => {
return {
places: state.places.places
};
};
export default connect(mapStateToProps)(FindPlaceScreen);
Place Details Screen
import React, { Component } from "react";
import { View, Text, Image, TouchableOpacity, StyleSheet } from "react-native";
import Icon from "react-native-vector-icons/Ionicons";
class PlaceDetail extends Component {
constructor(props) {
super(props);
}
render() {
return (
<View style={styles.modalContainer}>
<View>
<Image
source={this.props.navigation.state.params.image}
style={styles.placeImage}
/>
<Text style={styles.placeName}>
{this.props.navigation.state.params.namePlace}
</Text>
</View>
<View>
<TouchableOpacity onPress={props.onItemDeleted}>
<View style={styles.deleteButton}>
<Icon size={30} name="ios-trash" color="red" />
</View>
</TouchableOpacity>
<TouchableOpacity onPress={props.onModalClosed}>
<View style={styles.deleteButton}>
<Icon size={30} name="ios-close" color="red" />
</View>
</TouchableOpacity>
</View>
</View>
);
}
}
export default PlaceDetail;
You need to use react-native-navigation v2 for the find place screen
itemSelectedHandler = key => {
const selPlace = this.props.places.find(place => {
return place.key === key;
});
Navigation.push(this.props.componentId, {
component: {
name: 'PlaceDetail',
options: {
topBar: {
title: {
text: selPlace.name
}
}
},
passProps: {
selectedPlace: selPlace
}
}
});
};
make sure you import { Navigation } from "react-native-navigation";
Your PlaceDetail has some error
<TouchableOpacity onPress={props.onItemDeleted}>
<TouchableOpacity onPress={props.onModalClosed}>
Change props to this.props
<TouchableOpacity onPress={this.props.onItemDeleted}>
<TouchableOpacity onPress={this.props.onModalClosed}>
But I don't see onItemDeleted and onModalClosed anywhere, don't forget to pass those to PlaceDetail via props as well :)

Trouble getting function from different component

I'm new to react native. I am trying to get a 'Key' from a different component. I mean I am trying to call a function from a different component, as a parent component. But, I'm totally jumbled with all these reference calls and all. Please suggest to me how to call a function from a different component.
// AddScreen.js
import React, { Component } from 'react';
import { AppRegistry, AsyncStorage, View, Text, Button, TextInput, StyleSheet, Image, TouchableHighlight, Linking } from 'react-native';
import styles from '../components/styles';
import { createStackNavigator } from 'react-navigation';
import History from '../components/History';
export default class AddScreen extends Component {
constructor(props) {
super(props);
this.state = {
myKey: '',
}
}
getKey = async () => {
try {
const value = await AsyncStorage.getItem('#MySuperStore:key');
this.setState({ myKey: value });
} catch (error) {
console.log("Error retrieving data" + error);
}
}
async saveKey(value) {
try {
await AsyncStorage.setItem('#MySuperStore:key', value);
} catch (error) {
console.log("Error saving data" + error);
}
}
componentDidMount() {
this.getKey();
}
render() {
const { navigate } = this.props.navigation;
return (
<View style={styles.MainContainer}>
<View style={styles.Date_input}>
<TextInput
placeholder="Add input"
value={this.state.myKey}
onChangeText={(value) => this.saveKey(value)}
/>
</View>
<View style={styles.getKeytext}>
<Text >
Stored key is = {this.state.myKey}
</Text>
</View>
<View style={styles.Historybutton}>
<Button
onPress={() => navigate('History')}
title="Press Me"
/>
</View>
</View>
)
}
}
//History.js
import React, { Component } from 'react';
import AddScreen from '../components/AddScreen';
import {
AppRegistry,
StyleSheet,
Text,
TextInput,
Button,
View,
AsyncStorage
} from 'react-native';
export default class History extends Component {
constructor(props) {
super(props);
this.state = {
myKey: ''
}
}
render() {call async function synchronously
return (
<View style={styles.container}>
<Button
style={styles.formButton}
onPress={this.onClick}
title="Get Key"
color="#2196f3"
accessibilityLabel="Get Key"
/>
<Text >
Stored key is = {this.state.mykey}
</Text>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
padding: 30,
flex: 1,
backgroundColor: '#F5FCFF',
},
});
I just want to call the getKey function from the History component to get the myKey value on the History component's screen.
Please suggest to me, by taking my components as an example.
You just simply need to pass the key via navigation parameters.
<Button
onPress={() => navigate('History', { key: this.state.myKey })}
title="Press Me"
/>
and in your history component you can do
render() {
const key = this.props.navigation.getParam('key');
return (
// other code
)
}
You can read more about passing parameters here. https://reactnavigation.org/docs/en/params.html

Issue with photos length

I am facing 2 issues related to length of my selected photos:
When selecting photos, it lets me to select 5 photos without any issue (it fits my length restriction), however it doesn't save the chosen photos, when I go to the next screen. In another scenario, when I am at the same screen where I choose photos and I choose 6 photos, it selects the 6 photo but the warning popup will appear and say that its currently supports 5, then when I go to next screen its saves the selected photos unlike previously.
If I deselect photos and then try to select another photos (still in my length limit) popup jumps with selection limit and doesn't let me choose photos, when I go to the next screen it saves the changes from previous selection and not from current one.
import React from 'react';
import {
View,
ScrollView,
Image,
Dimensions,
TextInput,
Text,
StatusBar,
TouchableHighlight,
Linking,
Keyboard,
CameraRoll,
KeyboardAvoidingView
} from 'react-native';
import {connect} from 'react-redux';
import {ActionCreators} from '../redux/actions';
import {bindActionCreators} from 'redux';
import Colors from '../constants/Colors';
import api from '../api';
import {
getEmailAddress,
showError,
renderMessageBar,
registerMessageBar,
unregisterMessageBar
} from '../utils/ComponentUtils';
import {
regularHeader,
mainHeader
} from '../utils/Headers';
import {NavigationActions} from 'react-navigation';
import {SelectionLimitDialog} from '../utils/Dialogs';
import {ifIphoneX, isIphoneX} from 'react-native-iphone-x-helper';
import {SafeAreaView} from 'react-navigation';
// specific component imports.
import {List, ListItem} from 'react-native-elements'
import {Button} from 'react-native-elements'
import Loader from '../components/Loader';
import LoaderError from '../components/LoaderError';
import SelectedPhoto from '../components/SelectedPhoto';
class MultiSafeeScreen extends React.Component
{
static navigationOptions = ({navigation}) => {
const {params} = navigation.state;
const isIncome = params ? params.isIncome : false;
const notificationAction = params ? params.notificationAction : () => {};
const isShowBack = params ? params.isShowBack : false;
return mainHeader({
isShowBack: isShowBack,
backAction: () => navigation.goBack(),
notificationAction: () => notificationAction(),
income: isIncome
});
};
constructor(props) {
super(props);
this.selectedPhotos = [];
this.state = {
photos: null,
loader: {
loading: 0,
message: "Loading photos..."
},
selectedPhotos: [],
supportLength: 5
};
this.props.navigation.setParams({notificationAction: this.onNotification, isIncome: this.props.isNewNotifications});
}
UNSAFE_componentWillReceiveProps(newProps) {
if (newProps.isNewNotifications !== this.props.isNewNotifications) {
this.props.navigation.setParams({notificationAction: this.onNotification, isIncome: newProps.isNewNotifications});
}
}
componentDidMount() {
registerMessageBar(this.refs.alert);
let options = {
first: 30,
assetType: 'Photos',
}
CameraRoll.getPhotos(options)
.then(r => {
this.setState({
photos: r.edges,
loader: {
loading: 1,
message: "Loading photos..."
},
});
})
.catch((err) => {
//Error Loading Images
});
StatusBar.setHidden(false);
}
componentWillUnmount() {
unregisterMessageBar();
this.props.setSelectedPhotos(0);
}
onNotification = () => {
this.props.setNewNotifications(false);
this.props.navigation.navigate("Notifications");
}
closeKeyboard = () => {
Keyboard.dismiss();
}
onSelectPhoto = (photo, index) => {
let photos = new Set([...this.selectedPhotos]);
let len = photos.size + 1 ;
console.log('photos')
if (len > this.state.supportLength) {
this.limitDialog.open();
this.setState({selectedPhotos: this.selectedPhotos});
this.props.setSelectedPhotos(len);
}
else {
photos.add(photo);
this.selectedPhotos = Array.from(photos);
}
}
onDeselectPhoto = (photo, index) => {
let photos = new Set([...this.state.selectedPhotos]);
let len = photos.size - 1;
photos.delete(photo);
this.setState({selectedPhotos: Array.from(photos)});
this.props.setSelectedPhotos(len);
}
onNext = () => {
this.props.navigation.navigate("MultiSafeeCreate", {
isShowBack: true,
selected: [...this.state.selectedPhotos]
});
}
renderLoader() {
let {width, height} = Dimensions.get('window');
let photoWidth = width/3;
if (this.state.loader.loading === 0) {
return <Loader style={{justifyContent: 'center', alignItems: 'center'}} message={this.state.loader.message}/>
}
else if (this.state.loader.loading === 2) {
return <LoaderError style={{justifyContent: 'center', alignItems: 'center'}} message={this.state.loader.message}/>
}
// if photos are null do nothing, else if empty show onbording
// if has photos show photos.
if (this.state.photos === null) {
return <Loader style={{justifyContent: 'center', alignItems: 'center'}} message={this.state.loader.message}/>
}
else {
return (
<View style={{width: width, maxHeight: 600}}>
<ScrollView >
<View style={{flexDirection: 'row', width: width, flexWrap: 'wrap',marginBottom:40, justifyContent: 'space-between'}}>
{
this.state.photos.map((p, i) => {
return (
<SelectedPhoto
key={i}
index={i}
style={{
width: photoWidth,
height: photoWidth,
}}
borderColor = "white"
limit={this.state.supportLength}
photo={p}
onSelectPhoto={this.onSelectPhoto}
onDeselectPhoto={this.onDeselectPhoto}
/>
);
})
}
</View>
</ScrollView>
<View style={{ position:'absolute', right:-15, top:475 }}>
<Button
onPress={this.onNext}
containerViewStyle={{width: width}}
backgroundColor={Colors.red}
title='NEXT' />
</View>
</View>
);
}
}
render() {
return (
<View style={{flex: 1, backgroundColor: Colors.white}}>
{this.renderLoader()}
<SelectionLimitDialog ref={(el) => this.limitDialog = el} />
{renderMessageBar()}
</View>
);
}
}
function mapDispatchToProps(dispatch) {
return bindActionCreators(ActionCreators, dispatch);
}
function mapStatesToProps(state) {
return {
isNewNotifications: state.isNewNotifications
};
}
export default connect(mapStatesToProps, mapDispatchToProps)(MultiSafeeScreen);

How can I pass the string that reveals the qrcode to a variable in ReactNative?

I have followed many guides on interner but I have never managed to make it work. This class opens the qrcode scanner and should insert the string inside the 'qrcode' variable, but I just can not.
This is my class:
import React from 'react';
import { StyleSheet, Text, View, TextInput, AppRegistry, TouchableOpacity } from 'react-native';
import { Constants, BarCodeScanner, Permissions } from 'expo';
class HomeScreen extends React.Component {
render() {
return (
<Text style={styles.input}>
1) QRCode:
<Text style={styles.inputPos}> {qrcode} </Text>
</Text>
<TouchableOpacity
style={styles.button}
onPress={() => {
this.props.navigation.navigate('Details')}
}>
<Text> SCAN </Text>
</TouchableOpacity>
</View>
);
}
}
class ScanQRCode extends React.Component {
state = {
hasCameraPermission: null
};
componentDidMount() {
this._requestCameraPermission();
}
_requestCameraPermission = async () => {
const { status } = await Permissions.askAsync(Permissions.CAMERA);
this.setState({
hasCameraPermission: status === 'granted',
});
};
_handleBarCodeRead = data => {
Alert.alert(
'Scan successful!',
JSON.stringify(data)
);
qrcode = data;
};
render() {
return (
<View style={styles.container2}>
{this.state.hasCameraPermission === null ?
<Text>Requesting for camera permission</Text> :
this.state.hasCameraPermission === false ?
<Text>Camera permission is not granted</Text> :
<BarCodeScanner
onBarCodeRead={this._handleBarCodeRead}
style={{ height: 200, width: 200 }}
/>
}
</View>
);
}
}
I want the variable 'data' scanned by the qrcode to enter the variable 'qrcode' and display it next to it

navigate to another screen from tab-view screen not working

following is my code:- posting full code
index.android.js
import React, { Component } from 'react';
import { AppRegistry, Text, StyleSheet, View, NetInfo, Alert, AsyncStorage } from 'react-native';
import Splash from './app/screens/Splash'
import { StackNavigator } from 'react-navigation'
import Login from './app/screens/Login'
import Register from './app/screens/Register'
import Check from './app/screens/Check'
import Qwerty from './app/screens/Qwerty'
import Home from './app/screens/Home'
var STORAGE_KEY = 'token';
var DEMO_TOKEN;
class Splashscreen extends React.Component {
static navigationOptions = {
header: null
};
async componentDidMount() {
const { navigate } = this.props.navigation;
var DEMO_TOKEN = await AsyncStorage.getItem(STORAGE_KEY);
if (DEMO_TOKEN === undefined) {
navigate("Login");
} else if (DEMO_TOKEN === null) {
navigate("Splash");
} else {
navigate("Temp");
}
};
render() {
const { navigate } = this.props.navigation;
return(
<View style={styles.wrapper}>
<View style={styles.titlewrapper}>
<Text style={styles.title}> Loding... </Text>
</View>
</View>
);
}
}
const Section = StackNavigator({
Root: {screen: Splashscreen},
Splash: { screen: Splash },
Login: { screen: Login },
Registerscreen: { screen: Register },
Temp: { screen: Check },
Qwerty:{screen: Qwerty},
Home:{screen: Home},
});
AppRegistry.registerComponent('shopcon', () => Section);
here i can navigate properly without any error Now,
This is my tab.js => Here i given three tabs (mainly working in first home.js)
import React, { PureComponent } from 'react';
import { Animated, StyleSheet,View } from 'react-native';
import { TabViewAnimated, TabBar } from 'react-native-tab-view';
import { StackNavigator } from 'react-navigation';
import Qwerty from './Qwerty';
import Home from './Home';
//import Login from './Login'
import type { NavigationState } from 'react-native-tab-view/types';
type Route = {
key: string,
title: string,
};
type State = NavigationState<Route>;
class Tab extends PureComponent<void, *, State> {
static navigationOptions = {
header: null
};
state: State = {
index: 0,
routes: [
{ key: '1', title: 'Home' },
{ key: '2', title: 'Shops' },
{ key: '3', title: 'Bookmark' },
],
};
_first: Object;
_second: Object;
_third: Object;
_handleIndexChange = index => {
this.setState({
index,
});
};
_renderLabel = props => ({ route, index }) => {
const inputRange = props.navigationState.routes.map((x, i) => i);
const outputRange = inputRange.map(
inputIndex => (inputIndex === index ? '#fff' : '#222')
);
const color = props.position.interpolate({
inputRange,
outputRange,
});
return (
<View>
<Animated.Text style={[styles.label, { color }]}>
{route.title}
</Animated.Text>
</View>
);
};
_renderHeader = props => {
return (
<TabBar
{...props}
pressColor="#999"
// onTabPress={this._handleTabItemPress}
renderLabel={this._renderLabel(props)}
indicatorStyle={styles.indicator}
tabStyle={styles.tab}
style={styles.tabbar}
/>
);
};
_renderScene = ({ route }) => {
switch (route.key) {
case '1':
return (
<Home
ref={el => (this._first = el)}
style={[styles.page, { backgroundColor: '#E3F4DD' }]}
/>
);
case '2':
return (
<Qwerty
ref={el => (this._second = el)}
style={[styles.page, { backgroundColor: '#E6BDC5' }]}
initialListSize={1}
/>
);
case '3':
return (
<Qwerty
ref={el => (this._third = el)}
style={[styles.page, { backgroundColor: '#EDD8B5' }]}
initialListSize={1}
/>
);
default:
return null;
}
};
render() {
return (
<TabViewAnimated
style={[styles.container, this.props.style]}
navigationState={this.state}
renderScene={this._renderScene}
renderHeader={this._renderHeader}
onIndexChange={this._handleIndexChange}
// onRequestChangeTab={this._handleIndexChange}
lazy
/>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
indicator: {
backgroundColor: '#fff',
},
label: {
fontSize: 18,
fontWeight: 'bold',
margin: 8,
},
tabbar: {
backgroundColor: '#ff6600',
},
tab: {
opacity: 1,
// width: 140,
},
page: {
backgroundColor: '#f9f9f9',
},
});
export default Tab;
This is Home.js => It is running well if i am using it directly but not running when using it in Tab.js
GoPressed(navigate){
navigate("Registerscreen");
}
render() {
const { navigate } = this.props.navigation;
contents = this.state.qwerty.data.map((item) => {
return (
<View>
{item.p1.shareproductid ? <TouchableHighlight onPress={() => this.GoPressed(navigate)} style={styles.button}>
<Text style={styles.buttonText}>
Go
</Text>
</TouchableHighlight> : null }
<Text>
{item.p1.content}
</Text>
</View>
);
});
return (
<ScrollView style={styles.container}>
{contents}
</ScrollView>
);
}
I am trying to navigate on Register screen after Go button pressed, But here it shows me error. I have used same navigation method before they works correctly but here it gives error. please show where i am going wrong?
How to navigate to any other(not these three screens of tab-view ) screen from tab-view?
I tried running Home.js in other way means not using in tab view then it is running and navigation also works but when i am calling Home.js in tab-view i.e in Tab.js then it showing error as in screenshot.
Seems like you're navigating to the wrong screen name.
This should do it.
GoPressed(navigate){
navigate("Registerscreen");
}
I honestly can't test out your code as it'll take too much time.
How about you check out this simple working example of what your looking for and match it with your code.
Go the Settings tab and then you can click on the button to navigate to the other Registerscreen which is not in the Tabs.
https://snack.expo.io/HJ5OqS5qZ

Categories