How to remove submitted text input on React Native? - react-native

My code is working fine, it's pushing all the data to firebase as it should. I'm having no problems at all.
I just want to implement to remove the submitted data in text input. Since it stays there and you have to remove it manually.
I've been trying to add another function to 'onPress' to clear the inputs, but I can't seem to make it work. Any advice or help will be more than welcome.
Please check my code here below.
import { useState } from 'react';
import { StyleSheet, Text, View, TextInput, TouchableOpacity } from 'react-native';
import { addDoc, collection, doc, setDoc } from "firebase/firestore";
import { db } from './components/config';
export default function App() {
const [nombre, setNombre] = useState('');
const [cantidad, setCantidad] = useState('');
const [pretexto, setPretexto] = useState('');
function create(){
//Submit data
addDoc(collection(db, "users"), {
nombre: nombre,
cantidad: cantidad,
pretexto: pretexto
}).then(() => {
console.log('Data submitted');
}).catch((error) => {
console.log(error);
})
}
return (
<View style={styles.container}>
<View style={styles.textBox}>
<TextInput value ={nombre} onChangeText={(nombre) => {setNombre(nombre)}} placeholder='Nombre del caretubo' style={styles.inputOne}></TextInput>
<TextInput value={cantidad} onChangeText={(cantidad) => {setCantidad(cantidad)}} placeholder='Cantidad que debe el HP' style={styles.inputTwo}></TextInput>
<TextInput value={pretexto} onChangeText={(pretexto) => {setPretexto(pretexto)}} placeholder='Pretexto' style={styles.inputThree}></TextInput>
<TouchableOpacity style={styles.botonaso} onPress={() => {create; setNombre(''); }}>
<Text style={styles.botonasoTexto}>Subir</Text>
</TouchableOpacity>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
textBox: {
width: '100%',
padding: 12,
borderColor: 'gray',
borderWidth: 1,
borderRadius: 20,
},
inputOne: {
fontSize: 15,
},
inputTwo: {
fontSize: 15,
},
inputThree: {
fontSize: 15
},
botonaso: {
backgroundColor: '#202A44',
alignItems: 'center',
borderRadius: 20,
padding: 10
},
botonasoTexto: {
color: 'white'
}
});

const clearTextInputs = () => {
setNombre('');
setCantidad('');
setPretexto('');
};
function create() {
//Submit data
addDoc(collection(db, "users"), {
nombre: nombre,
cantidad: cantidad,
pretexto: pretexto
}).then(() => {
console.log('Data submitted');
clearTextInputs(); // <---------- add here
}).catch((error) => {
console.log(error);
})
}
<TouchableOpacity style={styles.botonaso} onPress={create}> // <----- onPress here
<Text style={styles.botonasoTexto}>Subir</Text>
</TouchableOpacity>

Related

React Native reload flatlist each time user hits the API

React, {useCallback, useState, useEffect, useRef} from 'react';
import {
View,
SafeAreaView,
FlatList,
Image,
Text,
TextInput,
TouchableOpacity,
StyleSheet,
ActivityIndicator,
} from 'react-native';
import Nodata from '../main/banking/common/Nodata';
import Icon from 'react-native-vector-icons/Ionicons';
import Toast from 'react-native-simple-toast';
import axios from 'axios';
import useSessionToken from '../hooks/useSessionToken';
import moment from 'moment';
import ListData from '../main/banking/common/ListData';
import {
widthPercentageToDP as wp,
heightPercentageToDP as hp,
} from 'react-native-responsive-screen';
import ShimmerPlaceholder from 'react-native-shimmer-placeholder';
import LinearGradient from 'react-native-linear-gradient';
function CustomerNotes(props) {
const session = useSessionToken();
const textInputRef = useRef();
const [notes, setNotes] = useState('');
const [data, setData] = useState({
notesList: [],
visible: false,
});
useEffect(() => {
getNotes();
}, [session,data]);
const getNotes = async () => {
try {
const qs = require('qs');
let params = qs.stringify({
cust_id: props.customerId,
operation: 'notes_list',
});
await axios
.post(
'https://abc.cdhgfhg.com/adghagsa',
params,
{
headers: {
Cookie: session?.token,
'Content-Type': 'application/x-www-form-urlencoded',
},
},
)
.then(function (response) {
if (response.data.status === 1) {
console.log('customernotes', response.data.data.hits.hits);
setData({
...data,
notesList: response.data.data.hits.hits,
visible: false,
});
}
})
.catch(function (error) {
console.log('CustomerNoteserror', error);
});
} catch (error) {
console.log('CustomerNoteserror', error);
}
};
const renderItem = ({item, index}) => {
var initialtv = Number(index + 1).toString();
var formattedDate = moment(item._source.added_on).format(
'ddd, MMM DD YYYY',
);
// console.log('initial', item, initialtv);
const data = {
text: item._source.notes,
mobile: formattedDate,
amount: '',
};
return <ListData item={data} />;
};
const handleInputSubmit = useCallback(ev => {
const input = ev.nativeEvent.text;
// validate all you want here
setNotes(input);
}, []);
const submitNotes = () => {
if (notes.length > 0) {
setData(prevState => ({
...prevState,
visible: true,
}));
addNotes();
} else {
Toast.show('Enter Notes');
}
};
const addNotes = async () => {
try {
const qs = require('qs');
let params = qs.stringify({
cust_id: props.customerId,
operation: 'add_notes',
notes: notes,
});
await axios
.post(
'https://abc.cdhgfhg.com/adghagsa',
params,
{
headers: {
Cookie: session?.token,
'Content-Type': 'application/x-www-form-urlencoded',
},
},
)
.then(function (response) {
if (response.data.status === 1) {
// console.log('addNotes', response.data);
getNotes();
}
})
.catch(function (error) {
console.log('addNoteserror', error);
});
} catch (error) {
console.log('CustomerNoteserror', error);
}
};
return (
<View style={{flex: 1, backgroundColor: 'white'}}>
{data.visible == true ? (
<ActivityIndicator
size="large"
color="#0096FF"
style={{
justifyContent: 'center',
alignItems: 'center',
position: 'absolute',
left: 0,
right: 0,
top: 0,
bottom: 0,
}}
/>
) : null}
{data.notesList.length != 0 ? (
<FlatList
data={data.notesList}
renderItem={renderItem}
style={{marginTop: hp('1.5%')}}
/>
) : (
<Nodata />
)}
<View
style={{
flex: 1,
flexDirection: 'row',
position: 'absolute',
bottom: 0,
marginBottom: '4%',
}}>
<TextInput
ref={textInputRef}
autoFocus={false}
style={styles.TextInputStyleClass}
placeholder="Write something"
placeholderTextColor={'#D0D0D0'}
onChangeText={
text => setNotes(text)
// (data.notes = text)
}
/>
<TouchableOpacity
onPress={() => submitNotes()}
style={{
height: 44,
width: 46,
backgroundColor: '#0096FF',
borderRadius: 6,
justifyContent: 'center',
alignItems: 'center',
elevation: 5,
marginRight: '4%',
}}>
<Icon
name={'send'}
size={20}
color="#ffffff"
style={{alignItems: 'center', justifyContent: 'center'}}
/>
</TouchableOpacity>
</View>
</View>
);
}
export default React.memo(CustomerNotes);
const styles = StyleSheet.create({
TextInputStyleClass: {
height: 45,
borderColor: '#0096FF',
flex: 7,
marginLeft: '4%',
marginRight: '4%',
flex: 1,
borderRadius: 6,
borderWidth: 1,
paddingLeft: 12,
fontFamily: 'Poppins-Medium',
fontSize: 14,
backgroundColor: 'white',
},
titleStyle: {
fontSize: 13,
color: '#000000',
fontFamily: 'Poppins-SemiBold',
},
subTitle: {
fontSize: 11,
fontFamily: 'Poppins',
color: '#000000',
},
});
I am fetching data from getNotes() API to render in Flatlist also I have a textinput at the bottom of the page. Whenever I submit textinput data to addNotes API data is added sucessfully and again I am calling getNotes API to reload the data in flatlist.
The issue is data rendering in flatlist is getting very slow and also the activityIndicator is not loading properly. When I call submitNotes the activityIndicator should start loading once the data is added and finished data rendering in flatlist the activityloader should stop loading.
To reload the flatlist each time the data changes you can pass extraData props. For performance optimizations, you can limit the number of items to be loaded at once using initialNumToRender, and onScroll more items will be loaded. Toggle refreshing props to true/false based on API response.
<FlatList
data={data.notesList}
renderItem={renderItem}
style={{marginTop: hp('1.5%')}}
keyExtractor={...}
extraData={data.noteList}
initialNumToRender={10}
refreshing={true}
/>

expo ImageManipulator returning [TypeError: undefined is not an object (evaluating '_expo.ImageManipulator.manipulate')]

for some reason
const manipResult = await ImageManipulator.manipulate(
image,
[{ resize: { width: 640, height: 480 } }],
{ format: 'jpg' }
);
returns [TypeError: undefined is not an object (evaluating '_expo.ImageManipulator.manipulate')]
which is weird because it worked one time and then this started to be returned by react native whenever it runs this line of code. so basically what im trying to do is resize the image and then send it to an api but for some reason it won't work and keeps giving this error even though data.uri isn't undefined
whole code
import React, { useState, useEffect, useRef } from 'react';
import { Text, View, StyleSheet, TouchableOpacity, Image } from 'react-native';
import Constants from 'expo-constants';
import { Camera, CameraType } from 'expo-camera';
import * as MediaLibrary from 'expo-media-library';
import { MaterialIcons } from '#expo/vector-icons';
import Button from './src/components/Button';
import axios from 'axios'
import { Buffer } from "buffer";
import * as FS from "expo-file-system";
import { ImageManipulator } from 'expo';
export default function App() {
const [hasCameraPermission, setHasCameraPermission] = useState(null);
const [image, setImage] = useState(null);
const [type, setType] = useState(Camera.Constants.Type.back);
const [flash, setFlash] = useState(Camera.Constants.FlashMode.off);
const cameraRef = useRef(null);
useEffect(() => {
(async () => {
MediaLibrary.requestPermissionsAsync();
const cameraStatus = await Camera.requestCameraPermissionsAsync();
setHasCameraPermission(cameraStatus.status === 'granted');
})();
}, []);
const takePicture = async () => {
if (cameraRef) {
try {
const data = await cameraRef.current.takePictureAsync();
console.log(data);
const manipResult = await ImageManipulator.manipulate(
data.uri,
[{ resize: { width: 640, height: 480 } }],
{ format: 'jpg' }
);
setImage(manipResult0);
} catch (error) {
console.log(error);
}
}
};
uriToBase64 = async (uri) => {
let base64 = await FS.readAsStringAsync(uri, {
encoding: FS.EncodingType.Base64,
});
return base64;
};
toServer = async (mediaFile) => {
const url = "api url";
let response = await FS.uploadAsync(url, mediaFile.uri, {
headers: {
"content-type": "image/jpeg",
},
httpMethod: "POST",
uploadType: FS.FileSystemUploadType.BINARY_CONTENT,
});
console.log(response);
};
const savePicture = async () => {
if(image) {
try {
const asset= await MediaLibrary.createAssetAsync(image);
await toServer({
type:"image",
base64: uriToBase64(image),
uri: image,
});
setImage(null);
console.log('saved successfully');
} catch (error) {
console.log(error);
}
}
};
if (hasCameraPermission === false) {
return <Text>No access to camera</Text>;
}
return (
<View style={styles.container}>
{!image ? (
<Camera
style={styles.camera}
type={type}
ref={cameraRef}
flashMode={flash}
>
<View
style={{
flexDirection: 'row',
justifyContent: 'space-between',
paddingHorizontal: 30,
}}
>
<Button
title=""
icon="retweet"
onPress={() => {
setType(
type === CameraType.back ? CameraType.front : CameraType.back
);
}}
/>
<Button
onPress={() =>
setFlash(
flash === Camera.Constants.FlashMode.off
? Camera.Constants.FlashMode.on
: Camera.Constants.FlashMode.off
)
}
icon="flash"
color={flash === Camera.Constants.FlashMode.off ? 'gray' : '#fff'}
/>
</View>
</Camera>
) : (
<Image source={{ uri: image }} style={styles.camera} />
)}
<View style={styles.controls}>
{image ? (
<View
style={{
flexDirection: 'row',
justifyContent: 'space-between',
paddingHorizontal: 50,
}}
>
<Button
title="Re-take"
onPress={() => setImage(null)}
icon="retweet"
/>
<Button title="Save" onPress={savePicture} icon="check" />
</View>
) : (
<Button title="Take a picture" onPress={takePicture} icon="camera" />
)}
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#000',
padding: 8,
},
controls: {
flex: 0.5,
},
button: {
height: 40,
borderRadius: 6,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
},
text: {
fontWeight: 'bold',
fontSize: 16,
color: '#E9730F',
marginLeft: 10,
},
camera: {
flex: 5,
borderRadius: 20,
},
topControls: {
flex: 1,
},
});

How to save form data into AsyncStorage and then automatically send that data into mongodb when internet is connected

I am trying to save the form submitted data into AsyncStorage and then automatically send that data into mongodb.
I have tried this. But it does not work. First time when i used the setItem it sets the item but now it is not setting the item.
I i put the code above the render then it gives me an error too many renders.
code
import React from 'react';
import { Text, View, Button, StyleSheet, TextInput, TouchableOpacity, Alert, Modal } from 'react-native';
import { useNetInfo } from '#react-native-community/netinfo';
import AsyncStorage from '#react-native-community/async-storage';
const App = () => {
const [text, onChangeText] = React.useState('');
const [number, onChangeNumber] = React.useState('');
const [data, setData] = React.useState('');
const [synched, setSynched] = React.useState('');
const netInfo = useNetInfo();
const submit = () => {
if (netInfo.isConnected) {
var inputData = {
"email": text,
"password": number
}
const storeData = async () => {
try {
await AsyncStorage.setItem("Data", JSON.stringify(inputData))
}
catch (e) {
Alert.alert(e)
}
}
}
else {
var inputData = {
"email": text,
"password": number
}
const storeData = async () => {
try {
await AsyncStorage.setItem("Data", JSON.stringify(inputData))
}
catch (e) {
Alert.alert(e)
}
}
}
}
if (netInfo.isConnected) {
var networkConn = <Text style={{ color: "green" }}>Back Online</Text>
}
else {
networkConn = <Text style={{ color: "red" }}>No internet</Text>
}
return (
<View>
<Modal
animationType="slide"
transparent={true}
visible={modalVisible}
onRequestClose={() => {
Alert.alert("Modal has been closed.");
setModalVisible(!modalVisible);
}}
></Modal>
<Text style={styles.text}>Signup Form</Text>
<TextInput
style={styles.input1}
onChangeText={onChangeText}
placeholder="Enter your email"
/>
<TextInput
style={styles.input1}
onChangeText={onChangeNumber}
placeholder="Enter your password"
secureTextEntry={true}
/>
<View style={styles.btnContainer}>
<TouchableOpacity>
<Button
style={{ fontSize: 20, color: 'green' }}
styleDisabled={{ color: 'red' }}
onPress={submit}
title="Sign Up"
>
</Button>
</TouchableOpacity>
</View>
<View>
<Text style={styles.text1}>{networkConn}</Text>
<Text style={styles.text1}>{synched}</Text>
<Text style={styles.text1}>{data}</Text>
</View>
</View>
)
}
const styles = StyleSheet.create({
text: {
marginTop: 50,
textAlign: 'center',
fontSize: 25,
fontWeight: 'bold',
color: 'blue'
},
text1: {
marginTop: 10,
textAlign: 'center',
fontSize: 12,
color: 'black'
},
input1: {
height: 40,
marginLeft: 50,
marginRight: 50,
marginTop: 30,
borderWidth: 1,
},
btnContainer: {
height: 100,
marginTop: 30,
width: 100,
alignSelf: "center"
},
});
export default App;
Putting data in render is not good idea.
Well you can use this flow:
Store the data offline if internet is not available but with extra parameter like isUploaded : false
Then when internet is back get data from the storage check whether the data parameter i.e isUploaded: false if it is false then upload the data and if you wanna keep it then you can otherwise remove the item from the asyncstorage.

Unhandled promise rejection: TypeError: undefined is not an object (evaluating 'camera.takePictureAsync') React-Native expo-camera

I am trying to create a function that will access my device's camera, and will allow me to take a picture, but I get the above error. I modeled this similar to requesting access to the camera roll and it works fine, but I cannot get it to work for the camera.
What may be causing this? Below is some of my code:
import * as ImagePicker from 'expo-image-picker' //I am using expo
import {Camera} from 'expo-camera'
export default function Photo(){
// Image Picker function start
useEffect(() => {
(async ()=> {
if (Platform.OS != 'web'){
const ( status !== 'granted') {
if(status !== 'granted) {
alert('Camera roll required to upload photo from your library');
}
}
})();
},[]);
//Image Picker function end
const camera = useRef(null) //added this
const takePicture = async () => { // added this
useEffect(() => {
(async () => {
if (Platform.OS !== 'web'){
const { status1 } = await Camera.requestPermissionsAsync();
if (status1 !== 'granted'){
alert('Camera required to take a photo');
}
} //added this
},
})();
}, [])
}
<Camera //added this
ref = { camera }
onGoogleVisionBarcodesDetected = {({barcodes}) => {
console.log(barcodes)
}}
/> //added this
<View style = {[ styles.button, {justifyContent: 'center', borderRadius: 20, backgroundColor: '#fff', paddingTop: 10, width: width*0.5, alignItems: 'center' } ]}>
<TouchableOpacity
color='#fff'
onPress = { ()=> takePicture () }
>
<Text style = {[ styles.button, {}]}>Take Photo </Text>
</TouchableOpacity>
</View>
This might help
import React, { useRef } from 'react'
import { View, Text, StyleSheet, TouchableOpacity } from 'react-native'
import { RNCamera } from 'react-native-camera'
function PlayWithCamera() {
const camera = useRef(null);
const takePicture = async () => {
const result1 = await camera.takePictureAsync();
....
};
return (
<View style={styles.container}>
<RNCamera
ref={camera}
.....
onGoogleVisionBarcodesDetected={({ barcodes }) => {
console.log(barcodes)
}}
/>
<View ... >
<TouchableOpacity
onPress={() => takePicture() } // change here
>
......
</TouchableOpacity>
</View>
</View>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'column',
backgroundColor: 'black',
},
preview: {
flex: 1,
justifyContent: 'flex-end',
alignItems: 'center',
},
capture: {
flex: 0,
backgroundColor: '#fff',
borderRadius: 5,
padding: 15,
paddingHorizontal: 20,
alignSelf: 'center',
margin: 20,
},
})
export default PlayWithCamera

How to use props in function which has navigation component

I'm trying to use props in function component. But the the function has navigation component in it like below.
const AddProductList = ({props, route, navigation}) => {
const {navData} = route.params;
var [data, setData] = useState(DATA);
...
...
...
}
because of route, navigation I think props is undefined.
I'm trying to write this example purely in functional style.
I need to do some thing like reading current data from flat list on tap.
var id = props.item.product_id_to_delete
because props is undefined I'm not getting item id to delete the tapped item.
Kindly anyone help me.
check full code
import React, {useState} from 'react';
import {View} from 'react-native-animatable';
import {
TextInput,
TouchableOpacity,
FlatList,
} from 'react-native-gesture-handler';
import Icon from 'react-native-vector-icons/FontAwesome';
import {StyleSheet, Pressable, Text, Button} from 'react-native';
import * as Animatable from 'react-native-animatable';
import Swipeout from 'react-native-swipeout';
import ButtonPressable from '../../components/ButtonPressable';
var sqlite_wrapper = require('./sqliteWrapper');
const DATA = [
{
prodName: 'Added data will look like this',
},
];
const AddProductList = ({item, route, navigation}) => {
const {navData} = route.params;
const [prodName, setProdName] = useState('');
var [data, setData] = useState(DATA);
const swipeSettings = {
style: {
marginBottom: 10,
},
autoClose: false,
backgroundColor: 'transparent',
close: false,
disabled: false,
onClose: (sectionID, rowId, direction) => {
console.log('---onclose--');
},
onOpen: (sectionID, rowId, direction) => {
console.log('---onopen--' + item);
},
right: [
{
backgroundColor: 'dodgerblue',
color: 'white',
text: 'Edit',
onPress: () => {
console.log('-----edit-----');
},
},
],
left: [
{
backgroundColor: 'red',
color: 'white',
text: 'Delete',
onPress: () => {
console.log('-----delete-----');
sqlite_wrapper.deleteById;
},
type: 'delete',
// component : (<ButtonPressable text="delete" />)
},
],
// buttonWidth: 100,
};
return (
<View style={styles.container}>
<Animatable.View
animation="bounceIn"
duration={1000}
style={styles.inputFieldView}>
<TextInput
style={styles.textInput}
onChangeText={(value) => setProdName(value)}
placeholder="Add the Product"
defaultValue={prodName}
/>
<TouchableOpacity
style={styles.addView}
onPress={() => {
sqlite_wrapper
.insert({prodName: prodName}, sqlite_wrapper.collection_product)
.then((result) => {
console.log('---result---');
console.log(result);
if (result.rowsAffected) {
fetchAllData();
}
});
function fetchAllData() {
sqlite_wrapper
.readAll(sqlite_wrapper.collection_product)
.then((resultData) => {
console.log('---resultData---');
console.log(resultData);
setData(resultData);
setProdName('');
});
}
// without sql this is how to update the state having a array
// const updatedArray = [...data];
// updatedArray.push({prodName: prodName});
// setData(updatedArray);
// setProdName('');
}}>
<Icon name="plus" size={16} style={styles.add} color="white" />
</TouchableOpacity>
</Animatable.View>
<Animatable.View
animation="bounceInLeft"
duration={1500}
style={{flex: 1}}>
<FlatList
data={data}
keyExtractor={(item) => item.id}
renderItem={({item, index}) => (
<Swipeout {...swipeSettings}>
<View style={styles.listView}>
<Text style={styles.listViewText}>{item.prodName}</Text>
</View>
</Swipeout>
)}
/>
</Animatable.View>
</View>
);
};
var styles = StyleSheet.create({
container: {
flex: 1,
},
inputFieldView: {
flexDirection: 'row',
alignItems: 'center',
alignSelf: 'stretch',
margin: 10,
},
textInput: {
flex: 1,
backgroundColor: '#b2ebf2',
borderTopLeftRadius: 7,
borderBottomLeftRadius: 7,
fontSize: 16,
},
addView: {
backgroundColor: '#0f4c75',
alignSelf: 'stretch',
alignItems: 'center',
justifyContent: 'center',
borderTopEndRadius: 7,
borderBottomEndRadius: 7,
padding: 9,
},
add: {
padding: 7,
},
listView: {
padding: 20,
backgroundColor: 'green',
margin: 0,
borderRadius: 0,
},
listViewText: {
color: 'white',
},
});
export default AddProductList;
change your component to this...
const AddProductList = ({item, route, navigation}) => {
const {navData} = route.params;
var [data, setData] = useState(DATA);
var id = item.product_id_to_delete
...
}
explanation: you are already doing object destruction, so props is all total i.e main parent, but navigation, route is the elements that
like:
props: {
navigation,
route,
...
}