Related
Here is my screen component with two textinputs from the link. I have removed some other code that isn't necessary to this issue.
When i choose the date from the popup it appears in the text input but doesnt get validated.
I cannot use the result of DatePicker component as it is , so i am doing some formating and saved to a function getDate.
How would you go about implemnting this ? is there any better way
enter image description here
import React, { useState, useContext, useEffect } from 'react';
import {
StyleSheet,
View,
Text,
TextInput,
TouchableOpacity,
ScrollView,
KeyboardAvoidingView,
Platform,
Image,
} from 'react-native';
import { icons, COLORS, } from '../constants';
import { Formik } from 'formik';
import * as yup from "yup";
import client from '../api/client';
import DateTimePickerModal from "react-native-modal-datetime-picker";
const addfarm = ({ navigation, Arrival_Date }) => {
const addFarmValidationSchema = yup.object().shape({
Farm_Code: yup.string().required('Please Enter the chick price'),
Arrival_Date: yup.string().required('Please Choose a date'),
});
const [isDatePickerVisible, setDatePickerVisibility] = useState(false);
const [date, setDate] = useState('');
const showDatePicker = () => {
setDatePickerVisibility(true);
};
const hideDatePicker = () => {
setDatePickerVisibility(false);
};
const handleConfirm = (date) => {
hideDatePicker();
setDate(date);
};
const getDate = () => {
let tempDate = JSON.stringify(date).split(/[ ",T,]/);
return date !== ''
? `${tempDate[1]}`
: '';
};
const newDate = getDate();
const addFarmInfo = {
Farm_Code: '',
Arrival_Date: '',
};
const add = async (values) => {
const res = await client({
method: 'POST',
url: '/Farm/SaveFarm',
data: JSON.stringify({ ...values, id })
})
.then(res => console.log(res.data))
.catch(err => console.log(err))
}
return (
<KeyboardAvoidingView
behavior={Platform.OS === 'ios' ? 'padding' : null}
style={{ flex: 1 }}>
<ScrollView style={styles.container}>
<Formik
initialValues={addFarmInfo}
validateOnMount={true}
onSubmit={add}
validationSchema={addFarmValidationSchema}>
{({
handleChange,
handleBlur,
handleSubmit,
values,
touched,
errors,
isValid,
setFieldValue,
}) => {
const {
Farm_Code,
Arrival_Date,
} = values
return (
<View
style={{
paddingHorizontal: '10%',
paddingTop: 50,
marginTop: 50,
backgroundColor: COLORS.main_background,
}}>
<Text style={styles.auth_text}>Add Farm</Text>
<Text style={styles.tag}>
Farm Code:
</Text>
<View
style={[styles.textInputView, { marginBottom: 10 }]}>
<TextInput
onChangeText={handleChange('Farm_Code')}
onBlur={handleBlur('Farm_Code')}
value={Farm_Code}
placeholder="Farm Code"
placeholderTextColor={COLORS.placeholder_fonts}
selectionColor={COLORS.drawer_button}
style={styles.textInput}
/>
<Image
source={!errors.Farm_Code ? icons.tick : icons.close}
resizeMode="stretch"
style={{
width: 18,
height: 18,
tintColor: !errors.Farm_Code ? COLORS.drawer_button : 'red',
alignItems: 'center',
marginRight: 10,
}}
/>
</View>
{(errors.Farm_Code && touched.Farm_Code) &&
<Text style={styles.errors}>{errors.Farm_Code}</Text>
}
<Text style={styles.tag}>
Arrival Date:
</Text>
<View
style={[styles.textInputView, { marginBottom: 10 }]}>
<TextInput
onChangeText={handleChange('Arrival_Date')}
onBlur={handleBlur('Arrival_Date')}
value={newDate}
onFocus={showDatePicker}
placeholder="yyyy/mm/dd"
placeholderTextColor={COLORS.placeholder_fonts}
selectionColor={COLORS.drawer_button}
style={styles.textInput}
/>
<TouchableOpacity style={{ marginRight: 10, }}
onPress={showDatePicker}
>
<DateTimePickerModal
isVisible={isDatePickerVisible}
mode="date"
onConfirm={handleConfirm}
onCancel={hideDatePicker}
/>
<Image
source={icons.calendar}
resizeMode="stretch"
style={{
width: 18,
height: 18,
tintColor: COLORS.secondary_fonts,
alignItems: 'center'
}}
/>
</TouchableOpacity>
<Image
source={!errors.Arrival_Date ? icons.tick : icons.close}
resizeMode="stretch"
style={{
width: 18,
height: 18,
tintColor: !errors.Arrival_Date ? COLORS.drawer_button : 'red',
alignItems: 'center',
marginRight: 10,
}}
/>
</View>
{(errors.Arrival_Date && touched.Arrival_Date) &&
<Text style={styles.errors}>{errors.Arrival_Date}</Text>
}
{(errors.Arrival_Date && touched.Arrival_Date) &&
<Text style={styles.errors}>{errors.Arrival_Date}</Text>
}
{/* Save */}
<TouchableOpacity
disabled={!isValid}
onPress={handleSubmit}
style={[styles.button, { backgroundColor: isValid ? COLORS.authButtons : COLORS.placeholder_fonts, marginTop: 10 }]}>
<Text style={styles.button_Text}>Save</Text>
</TouchableOpacity>
</View>
)
}
}
</Formik >
</ScrollView>
</KeyboardAvoidingView>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: COLORS.main_background,
},
textInput: {
flex: 1,
paddingLeft: 10,
color: 'black',
},
auth_text: {
fontSize: 20,
fontWeight: 'bold',
textAlign: 'center',
marginBottom: 5,
},
button: {
height: 50,
width: '100%',
marginVertical: 20,
borderRadius: 10,
alignItems: 'center',
justifyContent: 'center',
},
button_Text: {
fontSize: 18,
color: COLORS.white,
},
login_nav: {
fontSize: 12,
textAlign: 'center',
fontWeight: '400',
marginTop: 10,
},
errors: {
fontSize: 14,
color: 'red',
fontWeight: '400',
marginTop: 5,
},
textInputView: {
flex: 1,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
borderWidth: 1,
borderRadius: 10,
height: 50,
width: '100%',
borderColor: COLORS.secondary_fonts,
},
tag: {
color: 'black',
fontSize: 15,
marginBottom: 4,
marginLeft: 4
},
});
export default addfarm;
If you want formik to handle the validation, you should call the setFieldValue method and it will trigger the validation as the documentation says
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;
I have only two buttons, and I want their backgroundColor to be changed when pressing. I don't want to use map as there are only two buttons. I have tried some ways to approach what I expect, but I am at a loss what to do.
RoundedButtonSet :
const styles = StyleSheet.create({
container: {
marginBottom: 20,
},
});
const RoundedButtonSet = ({ firstBtn, secondBtn, contentStyle }) => {
return (
<View style={[styles.container, contentStyle]}>
<RoundedButtons firstBtn={firstBtn} secondBtn={secondBtn} />
</View>
);
};
RoundedButtons :
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
marginHorizontal: 15,
height: 40,
alignItems: 'center',
},
btn: {
flex: 1,
borderWidth: 1,
borderColor: colors.very_light_pink,
borderRadius: 6,
paddingVertical: 13,
height: 40,
},
btnTextStyle: {
fontSize: 12,
fontWeight: 'normal',
color: colors.very_light_pink_five,
textAlign: 'center',
},
left: {
borderTopRightRadius: 0,
borderBottomRightRadius: 0,
borderColor: colors.very_light_pink,
},
right: {
borderTopLeftRadius: 0,
borderBottomLeftRadius: 0,
borderLeftWidth: 0,
},
backgroundColor: {
backgroundColor: colors.iris,
},
textColor: {
color: colors.white_two,
},
});
const RoundedButtons = ({ firstBtn, secondBtn, contentStyle, onPress }) => {
const [isClicked, setIsClicked] = useState(true);
return (
<View style={[styles.container, contentStyle]}>
<TouchableOpacity
style={[styles.btn, styles.left, isClicked && styles.backgroundColor]}
onPress={() => setIsClicked(!isClicked)}
>
<Text style={[styles.btnTextStyle, isClicked && styles.textColor]}>
{firstBtn}
</Text>
</TouchableOpacity>
<TouchableOpacity
style={[styles.btn, styles.right]}
onPress={() => setIsClicked()}
>
<Text style={[styles.btnTextStyle]}>{secondBtn}</Text>
</TouchableOpacity>
</View>
);
};
RoundedButtons.propTypes = {
firstBtn: Text.propTypes,
secondBtn: Text.propTypes,
};
export default RoundedButtons;
Should I give index directly to each button? I have got this idea, but the problem is I have no idea how to access..
You can have a simple state to keep track of which button is pressed and use that to apply styles conditionally.
Here is the working example: Expo Snack
import React, { useState } from 'react';
import { Text, View, StyleSheet, TouchableOpacity } from 'react-native';
import Constants from 'expo-constants';
// You can import from local files
import AssetExample from './components/AssetExample';
// or any pure javascript modules available in npm
import { Card } from 'react-native-paper';
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
marginHorizontal: 15,
height: 40,
alignItems: 'center',
},
btn: {
flex: 1,
borderWidth: 1,
borderColor: 'pink',
borderRadius: 6,
paddingVertical: 13,
height: 40,
},
btnTextStyle: {
fontSize: 12,
fontWeight: 'normal',
color: 'pink',
textAlign: 'center',
},
left: {
borderTopRightRadius: 0,
borderBottomRightRadius: 0,
borderColor: 'pink',
},
right: {
borderTopLeftRadius: 0,
borderBottomLeftRadius: 0,
borderLeftWidth: 0,
},
backgroundColor: {
backgroundColor: 'black',
},
textColor: {
color: 'white',
},
});
const RoundedButtons = ({ firstBtn, secondBtn, contentStyle, onPress }) => {
const [clickedBtn, setIsClicked] = useState(null);
React.useEffect(() => {
console.log(clickedBtn);
}, [clickedBtn]);
return (
<View style={[styles.container, contentStyle]}>
<TouchableOpacity
style={[
styles.btn,
styles.left,
clickedBtn == 1 && styles.backgroundColor,
]}
onPress={() => setIsClicked(1)}>
<Text
style={[styles.btnTextStyle, clickedBtn == 1 && styles.textColor]}>
firstBtn
</Text>
</TouchableOpacity>
<TouchableOpacity
style={[
styles.btn,
styles.right,
clickedBtn == 2 && styles.backgroundColor,
]}
onPress={() => setIsClicked(2)}>
<Text
style={[styles.btnTextStyle, clickedBtn == 2 && styles.textColor]}>
secondBtn
</Text>
</TouchableOpacity>
</View>
);
};
RoundedButtons.propTypes = {
firstBtn: Text.propTypes,
secondBtn: Text.propTypes,
};
export default RoundedButtons;
Problem:
In my react native application I have used tochableOpacity for my buttons. I have created a custom button component and Have reused it through out the Application. My Custom button component is look like this.
const SubmitButton = (props) => {
const { onpress, btext, loadding, disabled, scrollView } = props;
const isLargeScreen = useIsLargeDevice();
return (
<TouchableOpacity
style={scrollView ? styles.sendButtonScrollView : styles.sendButton}
onPress={onpress}
disabled={disabled}>
{loadding ? (
<Image
source={spinner}
style={scrollView ? styles.bimageScrollview : styles.bimage}
/>
) : (
<Text
style={[
styles.sendButtonText,
isLargeScreen ? styles.largeText : styles.text,
]}>
{btext}
</Text>
)}
</TouchableOpacity>
);
};
export default SubmitButton;
const styles = StyleSheet.create({
sendButton: {
flex: 1,
backgroundColor: '#3e92ff',
paddingTop: '6%',
paddingBottom: '6%',
alignItems: 'center',
borderRadius: 50,
marginTop: 25,
justifyContent: 'center',
// flexWrap: 'wrap'
},
sendButtonScrollView: {
flex: 1,
backgroundColor: '#3e92ff',
paddingTop: '3%',
paddingBottom: '3%',
alignItems: 'center',
borderRadius: 50,
marginTop: 25,
justifyContent: 'center',
},
sendButtonText: {
fontFamily: 'Montserrat-Medium',
color: '#ffffff',
fontWeight: '300',
textAlign: 'center',
letterSpacing: 2,
},
text: {
fontSize: normalize(14),
},
largeText: {
fontSize: normalize(13),
},
bimage: {
width: 48,
height: 48,
},
bimageScrollview: {
width: 25,
height: 25,
},
});
And I have used it in another component like this.
Platform.OS === 'ios' ? Icon.loadFont() : null;
const handleBackButton = () => {
return true;
};
const _navigateToLogin = (navigation) => {
navigation.navigate('Login');
};
const _onPress = (values, validateToken) => {
validateToken(values.token);
};
const Tocken = (props) => {
useEffect(() => {
BackHandler.addEventListener('hardwareBackPress', handleBackButton);
}, [props.navigation]);
useEffect(() => {
if (props.validtoken === true) {
_navigateToLogin(props.navigation);
props.cleardata();
}
}, [props]);
return (
<KeyboardAvoidingView style={styles.container} enabled behavior={Platform.OS === 'ios' ? 'height' : null}>
<View style={styles.colmty} />
<View style={styles.formContainer}>
<AppText styles={styles.loginFormTitle}>
{strings('token.title')}
</AppText>
<Formik
initialValues={{
token: '',
}}
validationSchema={Yup.object({
token: Yup.string().required(strings('token.token-validation')),
})}
onSubmit={(values, formikActions) => {
_onPress(values, props.validatetoken);
setTimeout(() => {
formikActions.setSubmitting(false);
}, 500);
}}>
{(formprops) => (
<View>
<View
style={
!formprops.values.token &&
!formprops.errors.token &&
!props.hasError
? styles.inputView
: formprops.values.token &&
!formprops.errors.token &&
!props.hasError
? styles.validInputView
: styles.inputViewError
}>
<TextInput
style={styles.textField}
placeholder={strings('token.token_place_holder')}
placeholderTextColor="#bbbbbb"
value={formprops.values.token}
onChangeText={formprops.handleChange('token')}
onBlur={formprops.handleBlur('token')}
keyboardType="default"
/>
{formprops.errors.token || props.hasError ? (
<Icon
name="times"
size={normalize(15)}
style={styles.errorIcon}
/>
) : null}
{formprops.values.token &&
!formprops.errors.token &&
!props.hasError ? (
<Icon
name="check"
size={normalize(15)}
style={styles.validIcon}
/>
) : null}
</View>
{formprops.touched.token &&
formprops.errors.token &&
!props.hasError ? (
<View style={styles.errorMessage}>
<AppText styles={styles.errorMessageText}>
{formprops.errors.token}
</AppText>
</View>
) : null}
{props.hasError ? (
<View style={styles.errorMessage}>
<AppText styles={styles.errorMessageText}>
{props.error}
</AppText>
</View>
) : null}
<View style={styles.submitButtonView}>
<SubmitButton
btext={strings('token.submit')}
onpress={formprops.handleSubmit}
loadding={props.loadding}
disabled={props.loadding}
/>
</View>
</View>
)}
</Formik>
</View>
<View style={styles.colmty2} />
<View style={styles.hr} />
<View style={styles.versionContainer}>
<AppText styles={styles.version}>version: {version}</AppText>
</View>
</KeyboardAvoidingView>
);
};
const mapStateToProps = (state) => {
return {
loadding: state.signin.loadding,
validtoken: state.signin.validtoken,
hasError: state.signin.tokenEr,
error: state.signin.error,
};
};
const mapDispatchToProps = (dispatch) => {
return {
validatetoken: (value) => dispatch(signinActions.validatetoken(value)),
cleardata: () => dispatch(signinActions.cleardata()),
};
};
export default connect(mapStateToProps, mapDispatchToProps)(Tocken);
styles that I have used in the Token component is looks like this.
import {StyleSheet} from 'react-native';
import normalize from '_utils/fontsize';
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#ffffff',
},
colmty: {
height: '20%',
},
formContainer: {
height: '55%',
// backgroundColor: '#f2f2f2',
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
// elevation: 5,
padding: '10%',
justifyContent: 'center',
paddingBottom: '5%',
},
colmty2: {
height: '10%',
},
bottom: {
height: '15%',
justifyContent: 'center',
alignItems: 'center',
},
hr: {
borderBottomColor: '#c3c3c3',
borderBottomWidth: 2.0,
marginRight: '10%',
marginLeft: '10%',
},
validIcon: {
marginTop: 15,
color: '#3e92ff',
},
errorIcon: {
marginTop: 15,
color: '#ff3d3d',
},
textField: {
flex: 1,
fontFamily: 'Montserrat-Medium',
fontSize: normalize(15),
fontWeight: '500',
paddingLeft: 0,
},
inputView: {
marginTop: '5%',
flexDirection: 'row',
borderBottomColor: '#cccccc',
borderBottomWidth: 2,
},
validInputView: {
marginTop: '5%',
flexDirection: 'row',
borderBottomColor: '#3e92ff',
borderBottomWidth: 2,
},
inputViewError: {
marginTop: '5%',
flexDirection: 'row',
borderBottomColor: '#ff3d3d',
borderBottomWidth: 2,
},
patientFormTitle: {
fontSize: 30,
fontWeight: '200',
fontStyle: 'normal',
textAlign: 'center',
color: '#444444',
alignItems: 'center',
},
bottomLinkText: {
fontSize: 13,
color: '#484848',
borderBottomWidth: 2,
borderBottomColor: '#c3c3c3',
},
loginFormTitle: {
fontSize: normalize(16),
fontWeight: '200',
fontStyle: 'normal',
textAlign: 'center',
color: '#444444',
alignItems: 'center',
marginTop: '-10%',
},
errorMessageText: {
color: '#ff3d3d',
fontSize: normalize(13),
marginTop: 10,
},
spinnerContainer: {
marginTop: '50%',
alignItems: 'center',
},
versionContainer: {
marginRight: '10%',
marginLeft: '10%',
marginTop: '10%',
},
version: {
textAlign: 'center',
fontSize: normalize(12),
},
});
export default styles;
But button is not showing the text it looks like this.
I tried lot to find out where I have done wrong but I was unable to do so. Can someone help me to solve this issue.Thank you
i am trying to make a photo uploader to firebase in react native. I followed a tutorial and adopted the code 1-on-1. However, after I want to execute the code everything appears to work until the code has to be uploaded then I get the following error:
Possible Unhandled Promise Rejection (id: 0): Error: An unknown error
has occurred.
fn#http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:2132:45
http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:127402:44
putFile#http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:137147:104
uploadImage#http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:210966:91
touchableHandlePress#http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:54240:47
touchableHandlePress#[native code]
_performSideEffectsForTransition#http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:52872:36
_performSideEffectsForTransition#[native code]
_receiveSignal#http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:52798:46
_receiveSignal#[native code] touchableHandleResponderRelease#http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:52677:26
touchableHandleResponderRelease#[native code]
invokeGuardedCallbackImpl#http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:8997:21
invokeGuardedCallback#http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:9093:42
invokeGuardedCallbackAndCatchFirstError#http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:9097:36
executeDispatch#http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:9204:48
executeDispatchesInOrder#http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:9224:26
executeDispatchesAndRelease#http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:9329:35
forEach#[native code]
forEachAccumulated#http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:9319:22
runEventsInBatch#http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:9353:27
runExtractedPluginEventsInBatch#http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:9441:25
http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:10467:42
batchedUpdates$1#http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:21921:20
batchedUpdates#http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:10415:36
_receiveRootNodeIDEvent#http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:10466:23
receiveTouches#http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:10496:34
__callFunction#http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:2650:49
http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:2363:31
__guard#http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:2604:15
callFunctionReturnFlushedQueue#http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:2362:21
callFunctionReturnFlushedQueue#[native code]
Is anyone familiar with uploading images to firebase? in the tutorial they use uuid but for some reason the app breaks when I try to use this, so I left it out. this is the corresponding code:
import React, {Component} from 'react';
import {Platform, StyleSheet, Text, View, Image, Button, ScrollView, ImageBackground, Dimensions,TouchableOpacity, FlatList,
AsyncStorage} from 'react-native';
import { Avatar, ListItem } from 'react-native-elements';
import Icon from 'react-native-vector-icons/FontAwesome';
import ImagePicker from 'react-native-image-picker';
import firebase from 'react-native-firebase';
const SCREEN_WIDTH = Dimensions.get("window").width;
const list = [
{
title: '',
icon: 'cake',
url: 'ProfileSettings',
},
]
const options = {
title: 'Select Image',
storageOptions: {
skipBackup: true,
path: 'images'
}
};
const ImageRow = ({ image, windowWidth, popImage }) => (
<View>
<Image
source={{ uri: image }}
style={[styles.img, { width: windowWidth / 2 - 15 }]}
onError={popImage}
/>
</View>
);
class profileScreen extends Component {
constructor(props){
super(props);
this.state = {
first: '',
place: '',
province: '',
uid: '',
profileImg: '',
email: '',
imgSource: '',
uploading: false,
progress: 0,
images: []
}
}
getUserData = (user) => {
console.log(user);
let ref = firebase.database().ref('Users/' + user);
ref.on('value' , snapshot =>{
var state = snapshot.val();
this.setState({
first: state.firstname,
place: state.place,
province: state.province,
uid: user,
profileImg: state.profileImg,
birthday: state.birthday,
email: state.email,
year: state.registered.split("-",1)
})
})
}
componentDidMount(){
let user = firebase.auth().currentUser;
console.log(user);
console.log('test');
this.getUserData(user.uid);
let images;
AsyncStorage.getItem('images')
.then(data => {
images = JSON.parse(data) || [];
this.setState({
images: images
});
})
.catch(error => {
console.log(error);
});
}
/**
* Select image method
*/
pickImage = () => {
ImagePicker.showImagePicker(options, response => {
if (response.didCancel) {
console.log('You cancelled image picker 😟');
} else if (response.error) {
alert('And error occured: ', response.error);
} else {
const source = { uri: response.uri };
this.setState({
imgSource: source,
imageUri: response.uri
});
console.log(source);
}
});
};
/**
* Upload image method
*/
uploadImage = () => {
const ext = this.state.imageUri.split('.').pop(); // Extract image extension
const filename = `unique image' + ${ext}`; // Generate unique name
const imageRef = firebase.storage().ref('tutorials/images').child(filename +ext);
let mime = 'image/jpg';
imageRef.put(this.state.imageUri, { contentType: mime }).then((snapshot)=>{
console.log('Image uploaded successfully.')
}).catch((error)=>{
console.log('Image uploading failed:' + error);
});
};
/**
* Remove image from the state and persistance storage
*/
removeImage = imageIndex => {
let images = this.state.images;
images.pop(imageIndex);
this.setState({ images });
AsyncStorage.setItem('images', JSON.stringify(images));
};
render() {
const { uploading, imgSource, progress, images } = this.state;
const windowWidth = Dimensions.get('window').width;
const disabledStyle = uploading ? styles.disabledBtn : {};
const actionBtnStyles = [styles.btn, disabledStyle];
return (
<ScrollView style={styles.scorllVert}>
<View style={{ alignItems: 'flex-start', justifyContent: 'center', marginBottom: 40 }}>
<View style={styles.intro}>
<Text style={styles.introText}>Hoi, ik ben {this.state.first}{"\n"}<Text style={styles.introTextSpan}>Lid geworden in {this.state.year}</Text></Text>
{ this.state.profileImg ?
<Avatar size="large" rounded source={{uri: this.state.profileImg,}} onPress={() => console.log("Works!")} activeOpacity={0.7} />
:
<Avatar size="large" rounded title="GLR" onPress={() => console.log("Works!")} activeOpacity={0.7} />
}
</View>
<View style={styles.divider}>
</View>
<View style={styles.about}>
<Text style={styles.profileName}>Over</Text>
<View style={styles.aboutLiving}>
<Icon name='home' style={styles.icon}/>
<Text style={styles.aboutText}>Woont in {this.state.place}, {this.state.province}</Text>
</View>
</View>
<View style={styles.divider}>
</View>
<View style={styles.about}>
<Text style={styles.profileName}>Door {this.state.first} versterkt</Text>
<View style={styles.aboutLiving}>
<Icon name='check-circle' style={[styles.icon, styles.iconGreen]}/>
<Text style={styles.aboutText}>E-mail adres</Text>
</View>
</View>
<View style={styles.divider}>
</View>
<View style={styles.about}>
<Text style={styles.profileName}>Recente activiteiten</Text>
<Text >N.v.t.</Text>
<TouchableOpacity
style={actionBtnStyles}
onPress={this.pickImage}
disabled={uploading}
>
<View>
<Text style={styles.btnTxt}>Pick image</Text>
</View>
</TouchableOpacity>
{imgSource !== '' && (
<View>
<Image source={imgSource} style={styles.image} />
{uploading && (
<View
style={[styles.progressBar, { width: `${progress}%` }]}
/>
)}
<TouchableOpacity
style={actionBtnStyles}
onPress={this.uploadImage}
disabled={uploading}
>
<View>
{uploading ? (
<Text style={styles.btnTxt}>Uploading ...</Text>
) : (
<Text style={styles.btnTxt}>Upload image</Text>
)}
</View>
</TouchableOpacity>
</View>
)}
<View>
<Text
style={{
fontWeight: '600',
paddingTop: 20,
alignSelf: 'center'
}}
>
{images.length > 0
? 'Your uploaded images'
: 'There is no image you uploaded'}
</Text>
</View>
<FlatList
numColumns={2}
style={{ marginTop: 20 }}
data={images}
renderItem={({ item: image, index }) => (
<ImageRow
windowWidth={windowWidth}
image={image}
popImage={() => this.removeImage(index)}
/>
)}
keyExtractor={index => index}
/>
</View>
</View>
</ScrollView>
);
}
}
const styles = StyleSheet.create({
profileName:{
fontWeight: 'bold',
fontSize: 22,
marginTop: 20,
},
list:{
marginTop: 40,
width: '100%'
},intro:{
flex: 1,
flexDirection: 'row',
flexWrap: 'wrap',
alignItems: 'flex-start',
padding: 25,
marginBottom: 30,
paddingTop: 80,
},
introText:{
marginLeft: 0,
marginRight: 50,
fontSize: 22,
fontWeight: "700",
marginTop:15,
},
introTextSpan:{
marginLeft: 0,
marginRight: 40,
fontSize: 15,
fontWeight: "200",
marginTop:50,
},
divider:{
width: SCREEN_WIDTH-50,
padding: 10,
borderBottomColor: 'grey',
borderBottomWidth: 0.5,
marginTop: 10,
marginLeft: 25
},
about:{
paddingLeft: 25,
},
aboutLiving:{
flexDirection: 'row',
flexWrap: 'wrap',
alignItems: 'flex-start',
paddingTop: 10
},
icon:{
fontSize: 18
},
aboutText:{
marginLeft: 30
},
iconGreen:{
color: 'green'
}
,
button: {
marginTop: 30,
marginBottom: 20,
paddingVertical: 10,
alignItems: 'center',
backgroundColor: '#019BB4',
width: 300
},
buttonText: {
fontSize: 20,
fontWeight: 'bold',
color: '#fff'
},
scorllVert:{
marginBottom: 40
},
btn: {
paddingLeft: 20,
paddingRight: 20,
paddingTop: 10,
paddingBottom: 10,
borderRadius: 20,
backgroundColor: 'rgb(3, 154, 229)',
marginTop: 20,
alignItems: 'center'
},
disabledBtn: {
backgroundColor: 'rgba(3,155,229,0.5)'
},
btnTxt: {
color: '#fff'
},
image: {
marginTop: 20,
minWidth: 200,
height: 200,
resizeMode: 'contain',
backgroundColor: '#ccc',
},
img: {
flex: 1,
height: 100,
margin: 5,
resizeMode: 'contain',
borderWidth: 1,
borderColor: '#eee',
backgroundColor: '#ccc'
},
progressBar: {
backgroundColor: 'rgb(3, 154, 229)',
height: 3,
shadowColor: '#000',
}
})
export default profileScreen;
I am fairly new to react native and would like to upload images, is there anyone who can help me get this done? Even if there are other methods, I am open to that!
Try wrapping your uploadImage function in a try..catch and see if you can get a clearer error message in catch
Try this code for uploading the image,
const ext = this.state.imageUri.split('.').pop(); // Extract image extension
const filename = `unique image' + ${ext}`; // Generate unique name
const imageRef = firebase.storage().ref('tutorials/images).child(filename +ext);
let mime = 'image/jpg';
imageRef.put(this.state.imageUri, { contentType: mime }).then((snapshot)=>{
console.log('Image uploaded successfully.')
}).catch((error)=>{
console.log('Image uploading failed');
});