Invariant Violation: Element type is invalid: expected a string or a class/function but got: undefined. - react-native

Developers,
HELP. I'm getting this error with the below, I've been pouring over it trying to find the issue but just can't see it! What's wrong here? It seems to be stemming from the code from 146 to 236.
Invariant Violation: Element type is invalid: expected a string (for built-in >components) or a class/function (for composite components) but got: >undefined. You likely forgot to export your component from the file it's >defined in, or you might have mixed up default and named imports.
import React, { Component } from "react";
import PropTypes from "prop-types";
import {
View,
Text,
StyleSheet,
KeyboardAvoidingView,
LayoutAnimation,
UIManager,
Dimensions
} from "react-native";
import { Button, Input } from "react-native-elements";
import Icon from "react-native-vector-icons/FontAwesome";
import SimpleIcon from "react-native-vector-icons/SimpleLineIcons";
const SCREEN_WIDTH = Dimensions.get("window").width;
// Enable LayoutAnimation on Android
UIManager.setLayoutAnimationEnabledExperimental &&
UIManager.setLayoutAnimationEnabledExperimental(true);
const TabSelector = ({ selected }) => {
return (
<View style={styles.selectorContainer}>
<View style={selected && styles.selected} />
</View>
);
};
TabSelector.propTypes = {
selected: PropTypes.bool.isRequired
};
export default class AuthScreen extends Component {
constructor(props) {
super(props);
this.state = {
email: "",
password: "",
selectedCategory: 0,
isLoading: false,
isPasswordValid: true,
isConfirmationValid: true
};
this.selectCategory = this.selectCategory.bind(this);
this.login = this.login.bind(this);
this.signUp = this.signUp.bind(this);
}
selectCategory(selectedCategory) {
LayoutAnimation.easeInEaseOut();
this.setState({
selectedCategory,
isLoading: false
});
}
login() {
const { password } = this.state;
this.setState({ isLoading: true });
// Simulate an API call
setTimeout(() => {
LayoutAnimation.easeInEaseOut();
this.setState({
isLoading: false,
isPasswordValid: password.length >= 8 || this.passwordInput.shake()
});
}, 1500);
}
signUp() {
const { password, passwordConfirmation } = this.state;
this.setState({ isLoading: true });
// Simulate an API call
setTimeout(() => {
LayoutAnimation.easeInEaseOut();
this.setState({
isLoading: false,
isPasswordValid: password.length >= 8 || this.passwordInput.shake(),
isConfirmationValid:
password == passwordConfirmation || this.confirmationInput.shake()
});
}, 1500);
}
render() {
const {
selectedCategory,
isLoading,
isPasswordValid,
isConfirmationValid,
email,
password,
passwordConfirmation
} = this.state;
const isLoginPage = selectedCategory === 0;
const isSignUpPage = selectedCategory === 1;
return (
<View style={styles.container}>
<KeyboardAvoidingView
contentContainerStyle={styles.loginContainer}
behavior="position"
>
<View style={styles.titleContainer}>
<View style={{ flexDirection: "row" }}>
<Text style={styles.titleText}>BEAUX</Text>
</View>
<View style={{ marginTop: -10, marginLeft: 10 }}>
<Text style={styles.titleText}>VOYAGES</Text>
</View>
</View>
<View style={{ flexDirection: "row" }}>
<Button
disabled={isLoading}
clear
activeOpacity={0.7}
onPress={() => this.selectCategory(0)}
containerStyle={{ flex: 1 }}
titleStyle={[
styles.categoryText,
isLoginPage && styles.selectedCategoryText
]}
title={"Login"}
/>
<Button
disabled={isLoading}
clear
activeOpacity={0.7}
onPress={() => this.selectCategory(1)}
containerStyle={{ flex: 1 }}
titleStyle={[
styles.categoryText,
isSignUpPage && styles.selectedCategoryText
]}
title={"Sign up"}
/>
</View>
<View style={styles.rowSelector}>
<TabSelector selected={isLoginPage} />
<TabSelector selected={isSignUpPage} />
</View>
{/* //!ISSUE LIES HERE */}
<View style={styles.formContainer}>
<Input
leftIcon={
<Icon
name="envelope-o"
color="rgba(0, 0, 0, 0.38)"
size={25}
style={{ backgroundColor: "transparent" }}
/>
}
value={email}
keyboardAppearance="light"
autoFocus={false}
autoCapitalize="none"
autoCorrect={false}
keyboardType="email-address"
returnKeyType="next"
inputStyle={{ marginLeft: 10 }}
placeholder={"Email"}
containerStyle={{
borderBottomColor: "rgba(0, 0, 0, 0.38)"
}}
ref={input => (this.emailInput = input)}
onSubmitEditing={() => this.passwordInput.focus()}
onChangeText={email => this.setState({ email })}
/>
<Input
leftIcon={
<SimpleIcon
name="lock"
color="rgba(0, 0, 0, 0.38)"
size={25}
style={{ backgroundColor: "transparent" }}
/>
}
value={password}
keyboardAppearance="light"
autoCapitalize="none"
autoCorrect={false}
secureTextEntry={true}
returnKeyType={isSignUpPage ? "next" : "done"}
blurOnSubmit={true}
containerStyle={{
marginTop: 16,
borderBottomColor: "rgba(0, 0, 0, 0.38)"
}}
inputStyle={{ marginLeft: 10 }}
placeholder={"Password"}
ref={input => (this.passwordInput = input)}
onSubmitEditing={() =>
isSignUpPage ? this.confirmationInput.focus() : this.login()
}
onChangeText={password => this.setState({ password })}
errorMessage={
isPasswordValid ? null : "Please enter at least 8 characters"
}
/>
{isSignUpPage && (
<Input
icon={
<SimpleIcon
name="lock"
color="rgba(0, 0, 0, 0.38)"
size={25}
style={{ backgroundColor: "transparent" }}
/>
}
value={passwordConfirmation}
secureTextEntry={true}
keyboardAppearance="light"
autoCapitalize="none"
autoCorrect={false}
keyboardType="default"
returnKeyType={"done"}
blurOnSubmit={true}
containerStyle={{
marginTop: 16,
borderBottomColor: "rgba(0, 0, 0, 0.38)"
}}
inputStyle={{ marginLeft: 10 }}
placeholder={"Confirm password"}
ref={input => (this.confirmationInput = input)}
onSubmitEditing={this.signUp}
onChangeText={passwordConfirmation =>
this.setState({ passwordConfirmation })
}
errorMessage={
isConfirmationValid ? null : "Please enter the same password"
}
/>
)}
{/* //!ISSUE ENDS HERE */}
<Button
buttonStyle={styles.loginButton}
containerStyle={{ marginTop: 32, flex: 0 }}
activeOpacity={0.8}
title={isLoginPage ? "LOGIN" : "SIGN UP"}
onPress={isLoginPage ? this.login : this.signUp}
titleStyle={styles.loginTextButton}
loading={isLoading}
disabled={isLoading}
/>
</View>
</KeyboardAvoidingView>
<View style={styles.helpContainer}>
<Button
title={"Need help ?"}
titleStyle={{ color: "red" }}
buttonStyle={{ backgroundColor: "transparent" }}
underlayColor="transparent"
onPress={() => console.log("Account created")}
/>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
backgroundColor: "#034d84",
flex: 1
},
rowSelector: {
height: 20,
flexDirection: "row",
alignItems: "center"
},
selectorContainer: {
flex: 1,
alignItems: "center"
},
selected: {
position: "absolute",
borderRadius: 50,
height: 0,
width: 0,
top: -5,
borderRightWidth: 70,
borderBottomWidth: 70,
borderColor: "white",
backgroundColor: "white"
},
loginContainer: {
alignItems: "center",
justifyContent: "center"
},
loginTextButton: {
fontSize: 16,
color: "white",
fontWeight: "bold"
},
loginButton: {
backgroundColor: "rgba(232, 147, 142, 1)",
borderRadius: 10,
height: 50,
width: 200
},
titleContainer: {
height: 150,
backgroundColor: "transparent",
justifyContent: "center"
},
formContainer: {
backgroundColor: "white",
width: SCREEN_WIDTH - 30,
borderRadius: 10,
paddingTop: 32,
paddingBottom: 32,
alignItems: "center"
},
loginText: {
fontSize: 16,
fontWeight: "bold",
color: "white"
},
categoryText: {
textAlign: "center",
color: "white",
fontSize: 24,
fontFamily: "light",
backgroundColor: "transparent",
opacity: 0.54
},
selectedCategoryText: {
opacity: 1
},
titleText: {
color: "white",
fontSize: 30,
fontFamily: "regular"
},
helpContainer: {
height: 64,
alignItems: "center",
justifyContent: "center"
}
});

Based on your input that you are on react-native-elements version 0.19.1, it seems the Input component isn't available (see docs). Only the v1.0.0 beta versions support Input as component.

Related

add current time with text input

enter image description here Iam new with react native,so maybe my question seems silly to all excepts.I want to add current time in text input.(i designd todo app,that show the todo list,now i want to show time in todo list,for eg i enter todo(complete frontend)and add,that contain complete and delete button,now i want to add time in that(task adding time).my code are following below,
import React from 'react';
import {
StyleSheet,
SafeAreaView,
View,
TextInput,
Text,
FlatList,
TouchableOpacity,
Alert,
} from 'react-native';
import Icon from 'react-native-vector-icons/MaterialIcons';
import AsyncStorage from '#react-native-async-storage/async-storage';
const COLORS = {primary: '#1f145c', white: '#fff'};
const App = () => {
const \[todos, setTodos\] = React.useState(\[\]);
const \[textInput, setTextInput\] = React.useState('');
React.useEffect(() => {
getTodosFromUserDevice();
}, \[\]);
React.useEffect(() => {
saveTodoToUserDevice(todos);
}, \[todos\]);
const addTodo = () => {
if (textInput == '') {
Alert.alert('Error', 'Please input todo');
} else {
const newTodo = {
id: Math.random(),
task: textInput,
completed: false,
};
setTodos(\[...todos, newTodo\]);
setTextInput('');
}
};
const saveTodoToUserDevice = async todos => {
try {
const stringifyTodos = JSON.stringify(todos);
await AsyncStorage.setItem('todos', stringifyTodos);
} catch (error) {
console.log(error);
}
};
const getTodosFromUserDevice = async () => {
try {
const todos = await AsyncStorage.getItem('todos');
if (todos != null) {
setTodos(JSON.parse(todos));
}
} catch (error) {
console.log(error);
}
};
const markTodoComplete = todoId => {
const newTodosItem = todos.map(item => {
if (item.id == todoId) {
return {...item, completed: true};
}
return item;
});
setTodos(newTodosItem);
};
const deleteTodo = todoId => {
const newTodosItem = todos.filter(item => item.id != todoId);
setTodos(newTodosItem);
};
const clearAllTodos = () => {
Alert.alert('Confirm', 'Clear todos?', \[
{
text: 'Yes',
onPress: () => setTodos(\[\]),
},
{
text: 'No',
},
\]);
};
const ListItem = ({todo}) => {
return (
<View style={styles.listItem}>
<View style={{flex: 1}}>
<Text
style={{
fontWeight: 'bold',
fontSize: 20,
color: COLORS.primary,
textDecorationLine: todo?.completed ? 'line-through' : 'none',
}}>
{todo?.task}
</Text>
</View>
{!todo?.completed && (
<TouchableOpacity onPress={() => markTodoComplete(todo.id)}>
<View style={\[styles.actionIcon, {backgroundColor: 'green'}\]}>
<Icon name="done" size={20} color="white" />
</View>
</TouchableOpacity>
)}
<TouchableOpacity onPress={() => deleteTodo(todo.id)}>
<View style={styles.actionIcon}>
<Icon name="delete" size={20} color="white" />
</View>
</TouchableOpacity>
</View>
);
};
return (
<SafeAreaView
style={{
flex: 1,
backgroundColor: 'white',
}}>
<View style={styles.header}>
<Text
style={{
fontWeight: 'bold',
fontSize: 20,
color: COLORS.primary,
}}>
TODO APP
</Text>
<Icon name="delete" size={25} color="red" onPress={clearAllTodos} />
</View>
<FlatList
showsVerticalScrollIndicator={false}
contentContainerStyle={{padding: 20, paddingBottom: 100}}
data={todos}
renderItem={({item}) => <ListItem todo={item} />}
/>
<View style={styles.footer}>
<View style={styles.inputContainer}>
<TextInput
value={textInput}
placeholder="Add Todo"
onChangeText={text => setTextInput(text)}
/>
</View>
<TouchableOpacity onPress={addTodo}>
<View style={styles.iconContainer}>
<Icon name="add" color="white" size={30} />
</View>
</TouchableOpacity>
</View>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
footer: {
position: 'absolute',
bottom: 0,
width: '100%',
flexDirection: 'row',
alignItems: 'center',
paddingHorizontal: 20,
backgroundColor: COLORS.white,
},
inputContainer: {
height: 50,
paddingHorizontal: 20,
elevation: 40,
backgroundColor: COLORS.white,
flex: 1,
marginVertical: 20,
marginRight: 20,
borderRadius: 30,
},
iconContainer: {
height: 50,
width: 50,
backgroundColor: COLORS.primary,
elevation: 40,
borderRadius: 25,
justifyContent: 'center',
alignItems: 'center',
},
listItem: {
padding: 20,
backgroundColor: COLORS.white,
flexDirection: 'row',
elevation: 12,
borderRadius: 7,
marginVertical: 10,
},
actionIcon: {
height: 25,
width: 25,
backgroundColor: COLORS.white,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'red',
marginLeft: 5,
borderRadius: 3,
},
header: {
padding: 20,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
},
});
export default App;][1]
i got the answer ,answer is following below,
import React from 'react';
import {
StyleSheet,
SafeAreaView,
View,
TextInput,
Text,
FlatList,
TouchableOpacity,
Alert,
} from 'react-native';
import Icon from 'react-native-vector-icons/MaterialIcons';
import AsyncStorage from '#react-native-async-storage/async-storage';
const COLORS = {primary: '#1f145c', white: '#fff'};
const App = () => {
const [todos, setTodos] = React.useState([]);
const [textInput, setTextInput] = React.useState('');
React.useEffect(() => {
getTodosFromUserDevice();
}, []);
React.useEffect(() => {
saveTodoToUserDevice(todos);
}, [todos]);
const addTodo = () => {
if (textInput == '') {
Alert.alert('Error', 'Please input todo');
} else {
const newTodo = {
id: Math.random(),
task: textInput,
completed: false,
time: getCurrentTime()
};
setTodos([...todos, newTodo]);
setTextInput('');
}
};
const saveTodoToUserDevice = async todos => {
try {
const stringifyTodos = JSON.stringify(todos);
await AsyncStorage.setItem('todos', stringifyTodos);
} catch (error) {
console.log(error);
}
};
const getTodosFromUserDevice = async () => {
try {
const todos = await AsyncStorage.getItem('todos');
if (todos != null) {
setTodos(JSON.parse(todos));
}
} catch (error) {
console.log(error);
}
};
***const getCurrentTime = () => {
let today = new Date();
let date = today.getFullYear()+'-'+(today.getMonth()+1)+'-'+today.getDate();
let time = today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds();
let dateTime = date + '/' + time;
return dateTime;
}***
const markTodoComplete = todoId => {
const newTodosItem = todos.map(item => {
if (item.id == todoId) {
return {...item, completed: true};
}
return item;
});
setTodos(newTodosItem);
};
const deleteTodo = todoId => {
const newTodosItem = todos.filter(item => item.id != todoId);
setTodos(newTodosItem);
};
const clearAllTodos = () => {
Alert.alert('Confirm', 'Clear todos?', [
{
text: 'Yes',
onPress: () => setTodos([]),
},
{
text: 'No',
},
]);
};
const comdel = () => {
Alert.alert('select status', 'Complete or Delete', [
{
text: 'Delete',
onPress: () => setTodos([]),
},
{
text: 'Complete',
onPress: () => {markTodoComplete(todo.id)}
},
]);
};
const ListItem = ({todo}) => {
return (
<View style={styles.listItem}>
<View style={{flex: 1}}>
<Text
style={{
fontWeight: 'bold',
fontSize: 20,
color: COLORS.primary,
textDecorationLine: todo?.completed ? 'line-through' : 'none',
}}>
{todo?.task}
</Text>
</View>
{/* {!todo?.completed && (
<TouchableOpacity onPress={() => markTodoComplete(todo.id)}>
<View style={[styles.actionIcon, {backgroundColor: 'green'}]}>
<Icon name="done" size={20} color="white" />
</View>
</TouchableOpacity>
)} */}
{/* <TouchableOpacity onPress={() => deleteTodo(todo.id)}>
<View style={styles.actionIcon}>
<Icon name="delete" size={20} color="white" />
</View>
</TouchableOpacity> */}
<View>
<Text>
{todo?.time}
</Text>
</View>
<Icon name="menu" size={40} color="#a9a9a9" onPress={comdel} />
</View>
);
};
return (
<SafeAreaView
style={{
flex: 1,
backgroundColor: 'white',
}}>
<View style={styles.header}>
<Text
style={{
fontWeight: 'bold',
fontSize: 20,
color: COLORS.primary,
}}>
TODO APP
</Text>
<Icon name="delete" size={25} color="red" onPress={comdel} />
</View>
<FlatList
showsVerticalScrollIndicator={false}
contentContainerStyle={{padding: 20, paddingBottom: 100}}
data={todos}
renderItem={({item}) => <ListItem todo={item} />}
/>
<View style={styles.footer}>
<View style={styles.inputContainer}>
<TextInput
value={textInput}
placeholder="Add Todo"
onChangeText={text => setTextInput(text)}
/>
</View>
<TouchableOpacity onPress={addTodo}>
<View style={styles.iconContainer}>
<Icon name="add" color="white" size={30} />
</View>
</TouchableOpacity>
</View>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
footer: {
position: 'absolute',
bottom: 0,
width: '100%',
flexDirection: 'row',
alignItems: 'center',
paddingHorizontal: 20,
backgroundColor: COLORS.white,
},
inputContainer: {
height: 50,
paddingHorizontal: 20,
elevation: 40,
backgroundColor: COLORS.white,
flex: 1,
marginVertical: 20,
marginRight: 20,
borderRadius: 30,
},
iconContainer: {
height: 50,
width: 50,
backgroundColor: COLORS.primary,
elevation: 40,
borderRadius: 25,
justifyContent: 'center',
alignItems: 'center',
},
listItem: {
padding: 40,
backgroundColor: "#d3d3d3",
flexDirection: 'column',
elevation: 12,
borderRadius: 7,
marginVertical: 10,
},
actionIcon: {
height: 25,
width: 25,
backgroundColor: COLORS.white,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'red',
marginLeft: 5,
borderRadius: 3,
},
header: {
padding: 20,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
},
});
export default App;

Emailvalidator (require("email-validator") stopped working

I am doing email validation in my Signup form and all of a sudden it doesn't work anymore. I didn't change the signup.js file so it is a bit strange. I started working on the login.js file today so maybe there is some 'interference', but I don't have any idea where to look fist to be honest.
So here is the signup.js, where I put the emailvalidation that doesn't work anymore in bold.
import React, { Component } from 'react';
import { Text, StyleSheet, TouchableOpacity, Image, TextInput, View } from 'react-native';
import firebase from 'react-native-firebase';
var validator = require("email-validator");
export default class loginComponent extends Component {
constructor(props) {
super(props);
this.state = {firstName: ''};
this.state = {lastName: ''};
this.state = {email: ''};
this.state = {password: ''};
this.state = {emailValidated: false};
this.state = {errorMessage: null};
}
handleSignUp = () => {
firebase
.auth()
.createUserWithEmailAndPassword(this.state.email, this.state.password)
.then(() => this.props.navigation.navigate('Main'))
.catch(error => this.setState({ errorMessage: error.message }))
}
render() {
function renderEmailValidationState(emailInput) {
if(validator.validate(emailInput)) {
return false;
} else {
return true;
}
}
return (
<View style={styles.container}>
<View style={styles.logoContainer} >
<Image source={require('./assets/logo.png')} style={styles.logo}></Image>
<Text style={styles.slush}>
Lenen of huren, {"\n"} bij de buren!
</Text>
</View>
<View style={styles.formContainer}>
<View style={styles.inputTextFieldContainer}>
{this.state.errorMessage &&
<Text style={{ color: 'red' }}>
{this.state.errorMessage}
</Text>
}
<TextInput
style={styles.inputTextField}
placeholder="Enter you first name"
value={this.state.text}
backgroundColor="white"
onChangeText={(firstName) => this.setState({firstName})}
/>
<TextInput
style={styles.inputTextField}
placeholder="Enter you last name"
value={this.state.text}
backgroundColor="white"
onChangeText={(lastName) => this.setState({lastName})}
/>
<TextInput
style={styles.inputTextField}
placeholder="Enter your e-mail"
value={this.state.text}
backgroundColor="white"
onChangeText={(email) => this.setState({email})}
/>
<TextInput
style={styles.inputTextField}
placeholder="Enter your password"
value={this.state.password}
backgroundColor="white"
onChangeText={(password) => this.setState({password})}
/>
<TouchableOpacity
disabled= {renderEmailValidationState(this.state.email)}
style={styles.buttonContainer}
onPress={this.handleSignUp}
>
<View>
<Text style={styles.buttonText}>Sign up!</Text>
</View>
</TouchableOpacity>
<Text style={styles.plainText}>
Already a user?
</Text>
<TouchableOpacity
style={styles.buttonContainer}
onPress={() => this.props.navigation.navigate('Login')}
>
<View>
<Text style={styles.buttonText}>Login!</Text>
</View>
</TouchableOpacity>
</View>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 2,
padding:10,
backgroundColor:'#c6f1e7',
alignItems: 'stretch',
justifyContent: 'space-around'
},
logoContainer: {
padding: 10,
height: 250,
justifyContent: 'center' ,
alignItems: 'center'
},
logo: {
width: 250,
height: 250
},
slush: {
fontSize: 20,
color: '#59616e',
fontFamily: 'Raleway-Regular'
},
formContainer: {
flex:1,
padding: 10,
},
inputTextFieldContainer: {
padding: 100,
justifyContent: 'space-between',
alignItems: 'center',
marginBottom: 30
},
inputTextField: {
padding: 10,
height: 40,
width: 300,
marginBottom: 10,
fontSize: 16,
fontFamily: 'Raleway-Regular',
},
buttonContainer: {
padding: 10,
marginBottom: 20,
width: 300,
alignItems: 'center',
backgroundColor: '#acdcd7',
},
buttonText: {
padding: 1,
fontSize: 16,
color: '#59616e',
fontFamily: 'Raleway-Regular',
},
plainText: {
padding: 1,
fontSize: 16,
marginBottom: 5,
fontFamily: 'Raleway-Regular',
color: '#59616e'
},
});
And this is the login.js, but that is work in progress.
import React, { Component } from 'react';
import { Text, StyleSheet, TouchableOpacity, Image, TextInput, View } from 'react-native';
import firebase from 'react-native-firebase';
var validator = require("email-validator");
export default class loginComponent extends Component {
constructor(props) {
super(props);
this.state = {email: ''};
this.state = {password: ''};
this.state = {emailValidated: false};
this.state = {errorMessage: null};
}
render() {
function renderEmailValidationState(emailInput) {
if(validator.validate(emailInput)) {
return false;
} else {
return true;
}
}
return (
<View style={styles.container}>
<View style={styles.logoContainer}>
<Image source={require('./assets/logo.png')} style={styles.logo}></Image>
<Text style={styles.slush}>
Huren bij de buren!
</Text>
</View>
<View style={styles.formContainer}>
<View style={styles.inputTextFieldContainer}>
{this.state.errorMessage &&
<Text style={{ color: 'red' }}>
{this.state.errorMessage}
</Text>
}
<TextInput
style={styles.inputTextField}
placeholder="Enter your e-mail"
value={this.state.text}
backgroundColor="white"
onChangeText={(email) => this.setState({email})}
/>
<TextInput
style={styles.inputTextField}
placeholder="Enter your password"
value={this.state.password}
backgroundColor="white"
onChangeText={(password) => this.setState({password})}
/>
<TouchableOpacity
**disabled= {renderEmailValidationState(this.state.email)}**
style={styles.buttonContainer}
onPress={this.handleSignUp}
>
<View>
<Text style={styles.buttonText}>Sign up!</Text>
</View>
</TouchableOpacity>
<Text style={styles.plainText}>
Don't have an account?
</Text>
<TouchableOpacity
style={styles.buttonContainer}
onPress={() => this.props.navigation.navigate('SignUp')}
>
<View>
<Text style={styles.buttonText}>Register!</Text>
</View>
</TouchableOpacity>
</View>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 2,
padding:10,
backgroundColor:'#c6f1e7',
alignItems: 'stretch',
justifyContent: 'space-around'
},
logoContainer: {
padding: 10,
height: 350,
justifyContent: 'center' ,
alignItems: 'center'
},
logo: {
width: 250,
height: 250
},
slush: {
fontSize: 25,
color: '#59616e',
fontFamily: 'Raleway-Regular'
},
formContainer: {
flex:1,
padding: 10,
},
inputTextFieldContainer: {
padding: 100,
justifyContent: 'space-between',
alignItems: 'center',
marginBottom: 30
},
inputTextField: {
padding: 10,
height: 40,
width: 300,
marginBottom: 10,
fontSize: 16,
fontFamily: 'Raleway-Regular',
},
buttonContainer: {
padding: 10,
marginBottom: 20,
width: 300,
alignItems: 'center',
backgroundColor: '#acdcd7',
},
buttonText: {
padding: 1,
fontSize: 16,
color: '#59616e',
fontFamily: 'Raleway-Regular',
},
plainText: {
padding: 1,
fontSize: 16,
marginBottom: 5,
fontFamily: 'Raleway-Regular',
color: '#59616e'
},
});
Can anyone point me in the good direction?
Thanks a lot!
Tim
try this npm i raysk-vali
instead of email-validator.
usage:
const { isEmail } = require("raysk-vali");
isEmail("abc#example.com") // return true
isEmail("abcexample.com") // return false
for more checkout the documentation : https://www.npmjs.com/package/raysk-vali.

How to create dynamic checkbox in react native

I am able to create the dynamic checkbox but i need to check and uncheck it separately, right now if i check one everything gets checked and if i uncheck everything gets unchecked.
How to change the value of checkbox separately for each checkbox from state?
import React from 'react';
import {View,Text,StyleSheet,TouchableOpacity,Image,Switch,Platform,Dimensions,PixelRatio,} from'react-native';
import ImagePicker from 'react-native-image-picker';
import { Input, Button } from 'react-native-elements';
import { moderateScale } from 'react-native-size-matters';
const deviceWidth = Dimensions.get('window').width;
const deviceHeight = Dimensions.get('window').height;
const calcHeight = x => PixelRatio.roundToNearestPixel((deviceHeight * x) / 100);
const calcWidth = x => PixelRatio.roundToNearestPixel((deviceWidth * x) / 100);
class ErrorScreen extends React.Component {
constructor() {
super();
this.state = {
arr: [],
parkPay: false,
itemChecked: false,
index: null,
};
}
functionTwo = () => {
alert('func 2');
this.setState(() => ({
parkPay: true,
}));
};
checkedItem = index => {
console.log('this is index', index);
// let itemChecked = this.state.itemChecked
if (this.state.index != index) {
this.setState(() => ({
index: index,
itemChecked: !this.state.itemChecked,
}));
}
};
addParkField = () => {
console.log('jjjjj');
console.log(' ^^ props in parking form ^^ ', this.props);
let x = 0;
this.setState(() => ({
arr: [...this.state.arr, ''],
}));
// this.addFieldSecond()
// this.props.addParkFieldSecond()
};
render() {
return (
<View>
<View
style={{flex: 1, paddingRight: calcWidth(4),paddingLeft: calcWidth(6), paddingTop: calcHeight(4),paddingBottom: calcHeight(4),
}}>
<Input
placeholder="Enter Amount"
label="Enter Amount"
labelStyle={{ fontWeight: '200', color: 'black' }}
inputContainerStyle={{
paddingRight: calcWidth(2),
paddingLeft: calcWidth(2),
paddingTop: calcHeight(1),
paddingBottom: calcHeight(1),
}}
// onChangeText={this.props.parkingAmount}
/>
<Text style={[styles.error]}>{this.state.errors.Amount}</Text>
<View
style={{ paddingLeft: calcWidth(2), paddingTop: calcHeight(4) }}>
<View style={{ paddingRight: calcWidth(70) }}>
<Switch
value={this.state.parkPay}
style={
Platform.OS === 'ios' ? styles.switchIOS : styles.switchAND
}
// onValueChange={(value) => {this.props.toggleCustomerParkingPay(value); this.functionTwo()}}
/>
</View>
<Text style={{ paddingTop: calcHeight(8) }}>Paid By Customer</Text>
</View>
</View>
<View style={{}}>
{this.state.arr.map((extra, index) => {
return (
<View
style={{
flex: 1,
paddingRight: calcWidth(4),
paddingLeft: calcWidth(20),
paddingTop: calcHeight(15),
paddingBottom: calcHeight(4),
}}
key={index}>
<Input
placeholder="Enter Amount"
label="Enter Amount"
labelStyle={{ fontWeight: '200', color: 'black' }}
inputContainerStyle={{
paddingRight: calcWidth(2),
paddingLeft: calcWidth(2),
paddingTop: calcHeight(1),
paddingBottom: calcHeight(1),
}}
// onChangeText={this.handleAmount}
// onChangeText={this.props.parkingAmount}
/>
<Text style={[styles.error]}>{this.state.errors.Amount}</Text>
<View style={{ paddingTop: calcHeight(4) }}>
<View style={{ paddingRight: calcWidth(70) }}>
<Switch
value={this.state.parkPay}
style={
Platform.OS === 'ios'
? styles.switchIOS
: styles.switchAND
}
// onValueChange={(value) => {this.props.toggleCustomerParkingPay(value);}}
/>
</View>
<Text style={{ paddingTop: calcHeight(8) }}>
Paid By Customer
</Text>
</View>
</View>
);
})}
<View>
<View
style={{ paddingLeft: calcWidth(60), paddingTop: calcHeight(2) }}>
<TouchableOpacity
style={[styles.cardCirclePassenger]}
onPress={this.addParkField}>
<View
style={{
justifyContent: 'center',
alignItems: 'center',
paddingTop: calcHeight(2.2),
}}>
{/* <Image
style={{width: 24, height: 24}}
source={require('../../images/Group424.png')}
/> */}
<Text>Add</Text>
</View>
</TouchableOpacity>
</View>
</View>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
cardCirclePassenger: {
backgroundColor: '#31588A',
marginBottom: 10,
marginLeft: '5%',
width: 60,
height: 60,
borderRadius: 60 / 2,
borderColor: 'white',
shadowOpacity: 0.2,
shadowRadius: 1,
shadowOffset: {
width: 3,
height: 3,
},
borderWidth: 1,
},
switchIOS: {
transform: [
{ scaleX: moderateScale(0.7, 0.2) },
{ scaleY: moderateScale(0.7, 0.2) },
],
},
switchAND: {
transform: [
{ scaleX: moderateScale(1, 0.2) },
{ scaleY: moderateScale(1, 0.2) },
],
},
});
export default ErrorScreen;
i worked around a little bit and found the below way to generate dynamic checboxes along with separate state values. hope this helps someone.
The below code creates dynamic key-value pairs in state. if you console.log the state in your render you'll see (check0:true check1:true check2: false ....) .
<Switch
value={this.state[`check${key}`]}
onValueChange={value => this.setState({ [`check${key}`]: value })}
/>

React Native Scroll View bounces back to top

I am trying to implement a SrollView in my project however for some reason when I try to scroll through all the elements inside it, it springs back to the top of the ScrollView. I've looked around and some other questions were resolved by adding flex:1 to the ScrollView, however when I try that the entire ScrollView goes off screen. I've tried to add position:'absolute' to the ScrollView however that only leads to the scrollView not moving anymore
I've also tried experimenting with <KeyboardAwareScrollView> however the screen doesn't seem to adjust to the Input.
Here is my code:
import React from "react";
import {
View,
Dimensions,
Platform,
ActivityIndicator,
Alert,
Image,
KeyboardAvoidingView,
TouchableHighlight,
Keyboard
} from "react-native";
import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view'
import { Form, Item, Input, Label, Button, Text, Picker } from "native-base";
import * as firebase from "firebase";
import { ScrollView } from "react-native-gesture-handler";
import { LinearGradient, ImagePicker, Permissions } from "expo";
import Modal from "react-native-modal";
import uuid from "uuid";
import axios from "axios";
<View style={{borderBottomLeftRadius:20, borderBottomRightRadius:20, marginTop:20}}>
<TouchableHighlight onPress={this.toggleModal} underlayColor="white">
<Image source={{ uri: this.state.imageUrl }} style={{ width: SCREEN_WIDTH, height: SCREEN_HEIGHT/3, borderRadius: 20, marginBottom:20 }}/>
</TouchableHighlight>
</View>
}
{!this.state.loading ? (
<Button
full
style={{
fontFamily: "nunito",
backgroundColor: 'transparent',
alignSelf: "center",
height: SCREEN_HEIGHT/3,
width: SCREEN_WIDTH
}}
onPress={() => this.alertOptions()}
>
<View style={{flexDirection:'column'}}>
<Text
style={{
fontFamily: "nunito",
color: "black",
fontSize: 30,
textAlign: 'center'
}}
>
{this.state.imageUrl === ""
? "Tap"
: ""}
</Text>
<Text
style={{
fontFamily: "nunito",
color: "black",
fontSize: 30,
textAlign: 'center'
}}
>
{this.state.imageUrl === ""
? "to"
: ""}
</Text>
<Text
style={{
fontFamily: "nunito",
color: "black",
fontSize: 30,
textAlign:'center'
}}
>
{this.state.imageUrl === ""
? "Upload Photo"
: ""}
</Text>
</View>
</Button>
) : (
<Text style={{color:'white', textAlign:'center', fontSize: 40, marginTop: 25}}>Loading...Please Wait</Text>
)}
</View>
<View>
<ScrollView showsVerticalScrollIndicator={false} style={{ borderTopRightRadius: -20, borderTopLeftRadius: -20, backgroundColor:"#a2b6d8",}}>
<Text
style={{
fontSize: 28,
color: "#404040",
fontWeight: "700",
marginLeft: 12,
marginBottom: 10,
marginTop: 20,
textAlign: "center"
}}
>
Enter your details below
</Text>
<Form>
<Item stackedLabel rounded>
<Label style={{ fontFamily: "nunito" }}>
Address (Street, City)<Text style={{ color: "red", marginLeft: 10 }}>*</Text>
</Label>
<Input
placeholderTextColor="#9e9e9e"
placeholder="Required"
onChangeText={e => this.setState({ address: e })}
style={{ fontFamily: "nunito" }}
/>
</Item>
<Item stackedLabel>
<Label style={{ fontFamily: "nunito" }}>
Name
<Text style={{ color: "red", marginLeft: 10 }}>*</Text>
</Label>
<Input
placeholderTextColor="#9e9e9e"
placeholder="Required"
onChangeText={e => this.setState({ name: e })}
style={{ fontFamily: "nunito" }}
/>
</Item>
<Item stackedLabel>
<Label style={{ fontFamily: "nunito" }}>
Contractor{" "}
<Text style={{ color: "red", marginLeft: 10 }}>*</Text>
</Label>
<Input
placeholderTextColor="#9e9e9e"
placeholder="Required"
onChangeText={e => this.setState({ contractor: e })}
style={{ fontFamily: "nunito" }}
/>
</Item>
<Item stackedLabel>
<Label style={{ fontFamily: "nunito" }}>
Zip
<Text style={{ color: "red", marginLeft: 10 }}>*</Text>
</Label>
<Input
placeholderTextColor="#9e9e9e"
placeholder="Required"
onChangeText={e => this.setState({ zip: e })}
style={{ fontFamily: "nunito" }}
/>
</Item>
<Item stackedLabel>
<Label style={{ fontFamily: "nunito" }}>
Type of work performed
<Text style={{ color: "red", marginLeft: 10 }}>*</Text>
</Label>
<Input
placeholderTextColor="#9e9e9e"
placeholder="Required"
onChangeText={e => this.setState({ performed: e })}
style={{ fontFamily: "nunito" }}
/>
</Item>
</Form>
<View
style={{
flexDirection: "row",
justifyContent: "center",
alignItems: "center",
marginTop: 20,
marginBottom: 10
}}
>
</View>
<View
style={{
justifyContent:'space-around',
marginLeft: 15,
flexDirection:'row'
}}
>
{!this.state.loader ? (
<Button
full
style={{
fontFamily: "nunito",
backgroundColor: "#f3d95c",
width: SCREEN_WIDTH/3,
borderRadius:50,
shadowColor: "#918236",
shadowOffset: {
width: 0,
height: 0,
},
shadowOpacity: 0.8,
shadowRadius: 4,
// alignSelf: "center",
}}
onPress={() => this.add()}
>
<Text
style={{
fontFamily: "nunito",
color: "black",
fontSize: 22
}}
>
SEND
</Text>
</Button>
) : (
<ActivityIndicator size="large" color="#f3d95c" />
)}
<Button
onPress={() => this.logout()}
style={{ alignSelf: "center", marginBottom: 20, backgroundColor:'red', borderRadius:50 }}
>
<Text style={{fontSize:18}}>Logout</Text>
</Button>
</View>
</ScrollView>
</View>
Replace the content of the files.
EnterDetails.js
import React from "react";
import {
View,
Dimensions,
Platform,
ActivityIndicator,
Alert,
Image,
KeyboardAvoidingView,
TouchableHighlight,
TouchableWithoutFeedback,
Keyboard,
ScrollView
} from "react-native";
import { KeyboardAwareScrollView } from "react-native-keyboard-aware-scroll-view";
import { Form, Item, Input, Label, Button, Text, Picker } from "native-base";
import * as firebase from "firebase";
import { LinearGradient, ImagePicker, Permissions } from "expo";
import Modal from "react-native-modal";
import uuid from "uuid";
import axios from "axios";
const SCREEN_WIDTH = Dimensions.get("window").width;
const SCREEN_HEIGHT = Dimensions.get("window").height;
export default class EnterDetails extends React.Component {
constructor(props) {
super(props);
this.state = {
loader: false,
loading: false,
address: "",
name: "",
contractor: "",
zip: "",
email: "frank.gully2800#gmail.com",
// userEmail: firebase.auth().currentUser.email,
imageUrl: "",
performed: ""
};
}
state = {
isModalVisible: false
};
toggleModal = () => {
this.setState({ isModalVisible: !this.state.isModalVisible });
};
onValueChange(value) {
this.setState({
selected: value
});
}
imagePicker = () => {
Permissions.askAsync(Permissions.CAMERA_ROLL);
ImagePicker.launchImageLibraryAsync({
allowsEditing: false,
base64: true
}).then(async result => {
const blob = await new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.onload = function() {
resolve(xhr.response);
};
xhr.onerror = function(e) {
reject(new TypeError("Network request failed"));
};
xhr.responseType = "blob";
xhr.open("GET", result.uri, true);
xhr.send(null);
});
const ref = firebase
.storage()
.ref()
.child(uuid.v4());
const snapshot = await ref.put(blob);
blob.close();
let imageUrl = await snapshot.ref.getDownloadURL();
this.setState({ imageUrl: imageUrl, loading: false });
});
};
cameraUsage = () => {
this.setState({ loading: true });
Permissions.askAsync(Permissions.CAMERA);
ImagePicker.launchCameraAsync({
allowsEditing: false,
base64: true
}).then(async result => {
const blob = await new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.onload = function() {
resolve(xhr.response);
};
xhr.onerror = function(e) {
reject(new TypeError("Network request failed"));
};
xhr.responseType = "blob";
xhr.open("GET", result.uri, true);
xhr.send(null);
});
const ref = firebase
.storage()
.ref()
.child(uuid.v4());
const snapshot = await ref.put(blob);
blob.close();
let imageUrl = await snapshot.ref.getDownloadURL();
this.setState({ imageUrl: imageUrl, loading: false });
});
};
add = () => {
if (
this.state.zip !== "" &&
this.state.address !== "" &&
this.state.name !== "" &&
this.state.contractor !== "" &&
this.state.email !== "" &&
this.state.imageUrl !== "" &&
this.state.performed !== ""
) {
const {
name,
imageUrl,
contractor,
address,
email,
zip,
performed
} = this.state;
axios
.post(
"https://us-central1-cccproject-2b2f6.cloudfunctions.net/sendMailToUser",
{
zip: zip,
name: name,
imageUrl: imageUrl,
address: address,
email: email,
contractor: contractor,
performed: performed,
userEmail: this.state.userEmail
}
)
.then(response => {
Alert.alert("Details Sent");
})
.catch(error => {});
} else {
Alert.alert("Please Complete The form");
}
};
alertOptions = () => {
Alert.alert(
"Photo Options",
"Choose how you upload your photo",
[
{ text: "Camera", onPress: () => this.cameraUsage() },
{
text: "Image Library",
onPress: () => this.imagePicker()
},
{
text: "Cancel",
onPress: () => console.log("Day sayd no :("),
style: "cancel"
}
],
{ cancelable: false }
);
};
logout = () => {
firebase
.auth()
.signOut()
.then(s => {
this.props.navigation.navigate("Login");
})
.catch(e => {});
};
render() {
return (
<View style={{ flex: 1 }}>
<View
style={{
width: SCREEN_WIDTH,
height: SCREEN_HEIGHT / 3,
alignSelf: "center",
marginTop: 0,
backgroundColor: "red",
borderBottomLeftRadius: 20,
borderBottomRightRadius: 20
}}
>
{this.state.imageUrl === "" ? null : (
<View
style={{
borderBottomLeftRadius: 20,
borderBottomRightRadius: 20,
marginTop: 20
}}
>
<TouchableHighlight
onPress={this.toggleModal}
underlayColor="white"
>
<Image
source={{ uri: this.state.imageUrl }}
style={{
width: SCREEN_WIDTH,
height: SCREEN_HEIGHT / 3,
borderRadius: 20,
marginBottom: 20
}}
/>
</TouchableHighlight>
</View>
)}
{!this.state.loading ? (
<Button
full
style={{
fontFamily: "nunito",
backgroundColor: "transparent",
alignSelf: "center",
height: SCREEN_HEIGHT / 3,
width: SCREEN_WIDTH
}}
onPress={() => this.alertOptions()}
>
<View style={{ flexDirection: "column" }}>
<Text
style={{
fontFamily: "nunito",
color: "black",
fontSize: 30,
textAlign: "center"
}}
>
{this.state.imageUrl === "" ? "Tap" : ""}
</Text>
<Text
style={{
fontFamily: "nunito",
color: "black",
fontSize: 30,
textAlign: "center"
}}
>
{this.state.imageUrl === "" ? "to" : ""}
</Text>
<Text
style={{
fontFamily: "nunito",
color: "black",
fontSize: 30,
textAlign: "center"
}}
>
{this.state.imageUrl === "" ? "Upload Photo" : ""}
</Text>
</View>
</Button>
) : (
<Text
style={{
color: "white",
textAlign: "center",
fontSize: 40,
marginTop: 25
}}
>
Loading...Please Wait
</Text>
)}
</View>
<View style={{ borderWidth: 2, borderColor: "pink", flex: 1 }}>
<ScrollView
style={{
borderTopRightRadius: -20,
borderTopLeftRadius: -20,
backgroundColor: "#a2b6d8",
position: "relative",
flex: 1
}}
>
<Text
style={{
fontSize: 28,
color: "#404040",
fontWeight: "700",
marginLeft: 12,
marginBottom: 10,
marginTop: 20,
textAlign: "center"
}}
>
Enter your details below
</Text>
<Form>
<Item stackedLabel rounded>
<Label style={{ fontFamily: "nunito" }}>
Address (Street, City)
<Text style={{ color: "red", marginLeft: 10 }}>*</Text>
</Label>
<Input
placeholderTextColor="#9e9e9e"
placeholder="Required"
onChangeText={e => this.setState({ address: e })}
style={{ fontFamily: "nunito" }}
/>
</Item>
<Modal isVisible={this.state.isModalVisible}>
<Image
source={{ uri: this.state.imageUrl }}
style={{
width: SCREEN_WIDTH / 1.1,
height: SCREEN_HEIGHT / 1.1,
justifyContent: "center",
alignSelf: "center",
marginBottom: 0
}}
resizeMode="contain"
/>
<Button
style={{
backgroundColor: "red",
borderBottomRightRadius: 20,
borderBottomLeftRadius: 20,
borderTopLeftRadius: 20,
borderTopRightRadius: 20,
width: SCREEN_WIDTH - 20,
alignSelf: "center",
justifyContent: "center"
}}
onPress={this.toggleModal}
>
<Text style={{ fontFamily: "nunito", textAlign: "center" }}>
Close
</Text>
</Button>
</Modal>
<Item stackedLabel>
<Label style={{ fontFamily: "nunito" }}>
Name
<Text style={{ color: "red", marginLeft: 10 }}>*</Text>
</Label>
<Input
placeholderTextColor="#9e9e9e"
placeholder="Required"
onChangeText={e => this.setState({ name: e })}
style={{ fontFamily: "nunito" }}
/>
</Item>
<Item stackedLabel>
<Label style={{ fontFamily: "nunito" }}>
Contractor{" "}
<Text style={{ color: "red", marginLeft: 10 }}>*</Text>
</Label>
<Input
placeholderTextColor="#9e9e9e"
placeholder="Required"
onChangeText={e => this.setState({ contractor: e })}
style={{ fontFamily: "nunito" }}
/>
</Item>
<Item stackedLabel>
<Label style={{ fontFamily: "nunito" }}>
Zip
<Text style={{ color: "red", marginLeft: 10 }}>*</Text>
</Label>
<Input
placeholderTextColor="#9e9e9e"
placeholder="Required"
onChangeText={e => this.setState({ zip: e })}
style={{ fontFamily: "nunito" }}
/>
</Item>
<Item stackedLabel>
<Label style={{ fontFamily: "nunito" }}>
Type of work performed
<Text style={{ color: "red", marginLeft: 10 }}>*</Text>
</Label>
<Input
placeholderTextColor="#9e9e9e"
placeholder="Required"
onChangeText={e => this.setState({ performed: e })}
style={{ fontFamily: "nunito" }}
/>
</Item>
</Form>
<View
style={{
flexDirection: "row",
justifyContent: "center",
alignItems: "center",
marginTop: 20,
marginBottom: 10
}}
></View>
<View
style={{
justifyContent: "space-around",
marginLeft: 15,
flexDirection: "row"
}}
>
{!this.state.loader ? (
<Button
full
style={{
fontFamily: "nunito",
backgroundColor: "#f3d95c",
width: SCREEN_WIDTH / 3,
borderRadius: 50,
shadowColor: "#918236",
shadowOffset: {
width: 0,
height: 0
},
shadowOpacity: 0.8,
shadowRadius: 4
// alignSelf: "center",
}}
onPress={() => this.add()}
>
<Text
style={{
fontFamily: "nunito",
color: "black",
fontSize: 22
}}
>
SEND
</Text>
</Button>
) : (
<ActivityIndicator size="large" color="#f3d95c" />
)}
<Button
onPress={() => this.logout()}
style={{
alignSelf: "center",
marginBottom: 20,
backgroundColor: "red",
borderRadius: 50
}}
>
<Text style={{ fontSize: 18 }}>Logout</Text>
</Button>
</View>
</ScrollView>
</View>
</View>
);
}
}
App.js
import React from "react";
import { AppLoading } from "expo";
import * as Font from "expo-font";
import { Ionicons } from "#expo/vector-icons";
import Routes from "./Routes";
import { View, StatusBar } from "react-native";
import * as firebase from "firebase";
var firebaseConfig = {//ADD YOUR CREDS HERE};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
export default class App extends React.Component {
state = {
isReady: true,
isTrue: false
};
async componentWillMount() {
await Font.loadAsync({
...Ionicons.font,
Roboto: require("native-base/Fonts/Roboto.ttf"),
Roboto_medium: require("native-base/Fonts/Roboto_medium.ttf"),
nunito: require("./assets/nunito/Nunito-Regular.ttf"),
MonReg: require("./assets/Montserrat-Regular.ttf"),
MonBold: require("./assets/Montserrat-Bold.ttf")
});
this.setState({ isReady: false });
}
render() {
setTimeout(() => this.setState({ isTrue: true }), 6000);
if (this.state.isReady) {
return <AppLoading />;
}
return (
<View style={{ flex: 1 }}>
<StatusBar backgroundColor="rgba(255,255,255,1)" />
<Routes />
</View>
);
}
}

How to draw an arrow on every polyline segment on react-native-maps

hi i want to draw an arrow every polyline
like this image :
read this post :
How to draw an arrow on every polyline segment on Google Maps V3
this is answer my question but this post for javascript
but i use it and this is my code:
<View style={{ height: hp('50%'), width: wp('100%') }}>
<MapView
provider={PROVIDER_GOOGLE}
onLayout={this.onMapLayout}
style={styles.containerMap}
initialRegion={{
latitude: this.props.data ? this.props.data[0].YPOINT : '',
longitude: this.props.data ? this.props.data[0].XPOINT : '',
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}} >
{this.state.isMapReady && <Polyline
strokeWidth={2}
strokeColor="red"
geodesic={true}
icons={
icon = { path: google.maps.SymbolPath.FORWARD_CLOSED_ARROW },
offset = '100%'
}
coordinates={[...this.props.data.map((value, index) => {
return { latitude: value.YPOINT, longitude: value.XPOINT }
})]}
/>
}
</MapView>
</View>
but when run i get error 'google is not defined'.
UPDATE
this is function :
import React, { Component } from 'react'
import { Text, View, StyleSheet, ScrollView, AsyncStorage, ActivityIndicator, Alert, FlatList } from 'react-native'
import { widthPercentageToDP as wp, heightPercentageToDP as hp } from 'react-native-responsive-screen';
//import arrowIcon from '../../../assets/images/icon/Arrow/090.ico'
import SegmentedControlTab from "react-native-segmented-control-tab";
import { Dropdown } from 'react-native-material-dropdown';
import { getTraceOfHardware } from '../../../Store/actions';
import { connect } from 'react-redux';
import MapView, { Marker, PROVIDER_GOOGLE, Polyline } from 'react-native-maps';
import Icon from 'react-native-vector-icons/Entypo';
var moment = require('jalali-moment');
let dataDay = [{
value: 'امروز',
}, {
value: 'یک روز پیش',
}, {
value: 'دو روز پیش',
}, {
value: 'سه روز پیش',
}, {
value: 'چهار روز پیش',
}, {
value: 'پنج روز پیش',
}, {
value: 'شش روز پیش',
}, {
value: 'هفت روز پیش',
},];
const airplin = <Icon name="aircraft" size={30}/>
class mainRoutsReport extends Component {
constructor () {
super()
this.state = {
selectedIndex: 0,
selectedIndices: [0],
customStyleIndex: 0,
daySelected: '',
isMapReady: false,
tableHead: ['Head', 'Head2', 'Head3', 'Head4', 'Head5', 'Head6', 'Head7', 'Head8', 'Head9'],
widthArr: [40, 60, 80, 100, 120, 140, 160, 180, 200],
data: [],
latlon: []
// tableData: [
// ['1', '2', '3', '4', '5', '6'],
// ['1', '2', '3', '4', '5', '6']
// ]
}
}
//GET UDID
_retrieveUDID = async () => {
try {
return await AsyncStorage.getItem('#IranTracking:UDID', (error, result) => { return result })
} catch (error) {
// Error retrieving data
console.log(error)
}
};
//GET TOKEN
_retrieveToken = async () => {
try {
return await AsyncStorage.getItem('#IranTracking:Token', (error, result) => { return result })
} catch (error) {
// Error retrieving data
console.log(error)
}
};
//This method creat XML to send action.js to get List of Hardware from SOAP
async _makXML(value, index) {
udid = await this._retrieveUDID()
token = await this._retrieveToken()
var yesterday = moment().locale('fa').subtract(index + 0, 'day').format('YYYY-MM-DD')
// console.log(yesterday)
let xml = `<?xml version="1.0" encoding="utf-8"?>\
<x:Envelope xmlns:x="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tra="http://Trackinguri.org/">\
<x:Header>\
<tra:SOAPHeaderContent>\
<tra:UserName></tra:UserName>\
<tra:Password></tra:Password>\
<tra:Token>${token}</tra:Token>\
<tra:UID>${udid}</tra:UID>\
</tra:SOAPHeaderContent>\
</x:Header>\
<x:Body>\
<tra:GetTraceByHardwareID>\
<tra:HardwareID>${this.props.navigation.state.params.HID}</tra:HardwareID>\
<tra:FromDate>${yesterday} 00:00:00</tra:FromDate>\
<tra:ToDate>${yesterday} 23:59:59</tra:ToDate>\
<tra:HijriDates>true</tra:HijriDates>\
<tra:Time_Zone>Tehran</tra:Time_Zone>\
<tra:Lang>fa</tra:Lang>\
</tra:GetTraceByHardwareID>\
</x:Body>\
</x:Envelope>`;
console.log(" xml to get Tarce reports " + xml)
this.props.getTraceOfHardware(xml)
}
componentWillMount() {
this._makXML()
this.props.getTraceOfHardware()
}
componentDidMount() {
}
//this function use for day
_HandelDay(value, index) {
// var yesterday = moment().locale('fa').subtract(index,'day').format('YYYY-MM-DD')
//console.log('index of drop down is : ' + value + ' \nindex is : '+ index + '\n and date is : ' + yesterday)
//Alert.alert(yesterday)
}
handleMultipleIndexSelect = (index: number) => {
const { selectedIndices } = this.state
if (selectedIndices.includes(index)) {
this.setState(prevState => ({
...prevState,
selectedIndices: selectedIndices.filter((i) => i !== index),
}))
} else {
this.setState(prevState => ({
...prevState,
selectedIndices: [
...selectedIndices,
index,
],
}))
}
}
handleCustomIndexSelect = (index: number) => {
this.setState(prevState => ({ ...prevState, customStyleIndex: index }))
}
onMapLayout = () => {
this.setState({ isMapReady: true });
}
_renderItem = ({ item, index }) => (
// console.log(item)
<View style={{ flex: 1, height: hp('15%'), flexDirection: 'row', backgroundColor: index % 2 ? '#f3f3f3' : '#dedede', marginHorizontal: 5, alignItems: 'center' }} >
<View style={{ width: wp('15%'), alignItems: 'center', }}>
<Text style={{ marginLeft: 4, fontFamily: 'IRANSansMobile', }}>{item.TRUCKSTATE}</Text>
</View>
<View style={{ width: wp('12%'), alignItems: 'center' }}>
<Text style={{ marginLeft: 4, fontFamily: 'IRANSansMobile', }}>{item.SPEED}</Text>
</View>
<View style={{ width: wp('50%'), alignItems: 'center' }}>
<Text style={{ marginLeft: 4, fontFamily: 'IRANSansMobile', }}>{item.POSDESCRIPTION}</Text>
</View>
<View style={{ width: wp('10%'), alignItems: 'center' }}>
<Text style={{ marginLeft: 4, fontFamily: 'IRANSansMobile', }}>{item.SENTDATE}</Text>
</View>
<View style={{ width: wp('10%'), alignItems: 'center' }}>
<Text style={{ marginLeft: 4, fontFamily: 'IRANSansMobile', }}>{index + 1}</Text>
</View>
</View>
);
_renderHeadr = () => (
<View style={{ flexDirection: 'row', alignContent: 'space-between', alignItems: 'center', backgroundColor: '#5e9dcb' }}>
<View style={{ borderWidth: 0.5, width: wp('15%'), alignItems: 'center', borderTopLeftRadius: 5 }}>
<Text style={{ fontSize: 15, fontFamily: 'IRANSansMobile', }}>وضعیت</Text>
</View>
<View style={{ borderWidth: 0.5, width: wp('12%'), alignItems: 'center' }}>
<Text style={{ fontSize: 15, fontFamily: 'IRANSansMobile', }}>سرعت</Text>
</View>
<View style={{ borderWidth: 0.5, width: wp('50%'), alignItems: 'center' }}>
<Text style={{ fontSize: 15, fontFamily: 'IRANSansMobile', }}>موقعیت</Text>
</View>
<View style={{ borderWidth: 0.5, width: wp('10%'), alignItems: 'center' }}>
<Text style={{ fontSize: 15, fontFamily: 'IRANSansMobile', }}>زمان</Text>
</View>
<View style={{ borderWidth: 0.5, width: wp('10%'), alignItems: 'center', borderTopRightRadius: 5 }}>
<Text style={{ fontSize: 15, fontFamily: 'IRANSansMobile', }}>ردیف</Text>
</View>
</View>
);
render() {
const { customStyleIndex } = this.state
//console.log(this.props.navigation.state.params.HID)
//console.log(this.props.data)
return (
<View style={{ width: wp('100%'), height: hp('100%') }}>
<Dropdown animationDuration={100}
dropdownMargins={{ min: 0, max: 0 }}
dropdownOffset={{ top: 0, left: 0 }}
style={{ textAlign: 'center' }}
containerStyle={{ textAlign: 'right', backgroundColor: '#fcee97', borderWidth: 0.5, borderRadius: 13, margin: 8 }}
absoluteRTLLayout={true}
data={dataDay}
dropdownPosition={-5}
onChangeText={(value, index) => this._makXML(value, index)}
value={dataDay[0].value} />
<SegmentedControlTab
values={['نمایش متنی', 'نمایش نقشه']}
selectedIndex={customStyleIndex}
onTabPress={this.handleCustomIndexSelect}
borderRadius={0}
tabsContainerStyle={{ height: 50, backgroundColor: '#F2F2F2' }}
tabStyle={{ backgroundColor: '#ffffff', borderWidth: 0, borderColor: 'transparent' }}
activeTabStyle={{ backgroundColor: '#5e9dcb', marginTop: 2 }}
tabTextStyle={{ color: '#000000', fontWeight: 'bold', fontFamily: 'IRANSansMobile' }}
activeTabTextStyle={{ color: '#ffffff', fontFamily: 'IRANSansMobile' }}
/>
{//table
customStyleIndex === 0
&&
<View style={{ paddingBottom: wp('20%') }}>
{this.props.isLoading ? <ActivityIndicator /> : <FlatList
ListHeaderComponent={this._renderHeadr}
stickyHeaderIndices={[0]}
data={this.props.data}
renderItem={this._renderItem}//({item})=>(this._renderItem)
keyExtractor={(item, index) => index.toString()}
/>}
</View>
}
{//Map
customStyleIndex === 1
&&
<View style={{ height: hp('50%'), width: wp('100%') }}>
<MapView
provider={PROVIDER_GOOGLE}
onLayout={this.onMapLayout}
style={styles.containerMap}
initialRegion={{
latitude: this.props.data ? this.props.data[0].YPOINT : '',
longitude: this.props.data ? this.props.data[0].XPOINT : '',
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}} >
{this.state.isMapReady &&
<Polyline
strokeWidth={2}
strokeColor="red"
geodesic={true}
icons={
icon = {airplin },
offset = '100%'
}
coordinates={[...this.props.data.map((value, index) => {
return { latitude: value.YPOINT, longitude: value.XPOINT }
})]}
/>
}
</MapView>
</View>
}
</View>
)
}
}
function mapStateToProps(state) {
console.log(state)
return {
data: state.GetTraceHardware.data,
isLoading: state.GetTraceHardware.isLoading,
error: state.GetTraceHardware.error
}
}
function mapDispatchToProps(dispatch) {
return {
getTraceOfHardware: (data) => dispatch(getTraceOfHardware(data))
}
}
export default connect(mapStateToProps, mapDispatchToProps)(mainRoutsReport);