How to scan one barcode per time? [react-native-camera] - javascript

Actually i'm new to React and i'm trying to make a simple barcode scanner which show the scanned barcode in an alert and after pressing "OK" in the alert the user should be able to scan another barcode.
The issue is that the barcode is continuously scanned and when the alert is up it's hiding and showing every second the alert.
I was trying to do something like this to show the alert only once and if OK is pressed to be able to show again the alert but only in case the OK is pressed but that had no effect..
onBarCodeRead = (e) => {
if(!this.alertPresent){
this.alertPresent = true;
Alert.alert(
"Barcode type is " + e.type,
"Barcode value is " + e.data,
[
{text: 'OK', onPress: () => this.alertPresent = false;},
],
{cancelable: false},
);
}
}
Here is full code of Barcode.JS
import React, { Component } from 'react';
import { Button, Text, View,Alert } from 'react-native';
import { RNCamera } from 'react-native-camera';
import BarcodeMask from 'react-native-barcode-mask';
class ProductScanRNCamera extends Component {
constructor(props) {
super(props);
this.camera = null;
this.barcodeCodes = [];
this.alertPresent = false;
this.state = {
camera: {
flashMode: RNCamera.Constants.FlashMode.auto,
}
};
}
onBarCodeRead = (e) => {
if(!this.alertPresent){
this.alertPresent = true;
Alert.alert(
"Barcode type is " + e.type,
"Barcode value is " + e.data,
[
{text: 'OK', onPress: () => this.alertPresent = false;},
],
{cancelable: false},
);
}
}
pendingView() {
return (
<View
style={{
flex: 1,
backgroundColor: 'lightgreen',
justifyContent: 'center',
alignItems: 'center',
}}
>
<Text>Waiting</Text>
</View>
);
}
render() {
return (
<View style={styles.container}>
<RNCamera
ref={ref => {
this.camera = ref;
}}
defaultTouchToFocus
flashMode={this.state.camera.flashMode}
mirrorImage={false}
onBarCodeRead={this.onBarCodeRead.bind(this)}
onFocusChanged={() => {}}
onZoomChanged={() => {}}
style={styles.preview}
>
<BarcodeMask/>
</RNCamera>
</View>
);
}
}

The trick here is to modify barcodeTypes props with an internal state.
const defaultBarcodeTypes = [// should be all Types from RNCamera.Constants.BarCodeType];
class ProductScanRNCamera extends Component {
state = {
// your other states
barcodeType: '',
barcodeValue: '',
isBarcodeRead: false // default to false
}
onBarcodeRead(event) {
this.setState({isBarcodeRead: true, barcodeType: event.type, barcodeValue: event.data});
}
// run CDU life-cycle hook and check isBarcodeRead state
// Alert is a side-effect and should be handled as such.
componentDidUpdate() {
const {isBarcodeRead, barcodeType, barcodeValue} = this.state;
if (isBarcodeRead) {
Alert.alert(barcodeType, barcodeValue, [
{
text: 'OK',
onPress: () => {
// Reset everything
this.setState({isBarcodeRead: false, barcodeType: '', barcodeValue: ''})
}
}
]);
}
}
render() {
const {isBarcodeRead} = this.state;
return (
<RNCamera {...your other props} barcodeTypes={isBarcodeRead ? [] : defaultBarcodeTypes}>
<BarcodeMask />
</RNCamera>
)
}
}
A hook version is cleaner
const ProductScanRNCamera = () => {
const [isBarcodeRead, setIsBarcodeRead] = useState(false);
const [barcodeType, setBarcodeType] = useState('');
const [barcodeValue, setBarcodeValue] = useState('');
useEffect(() => {
if (isBarcodeRead) {
Alert.alert(
barcodeType,
barcodeValue,
[
{
text: 'OK',
onPress: () => {
// reset everything
setIsBarcodeRead(false);
setBarcodeType('');
setBarcodeValue('');
}
}
]
);
}
}, [isBarcodeRead, barcodeType, barcodeValue]);
const onBarcodeRead = event => {
if (!isBarcodeRead) {
setIsBarcodeRead(true);
setBarcodeType(event.type);
setBarcodeValue(event.data);
}
}
return (
<RNCamera {...your props}
onBarCodeRead={onBarcodeRead}
barcodeTypes={isBarcodeRead ? [] : defaultBarcodeTypes}>
<BarcodeMask />
</RNCamera>
)
}

use setState in order to set state of component.setState will take the object and update the state of component
check code below
import React, { Component } from 'react';
import { Button, Text, View, Alert } from 'react-native';
import { RNCamera } from 'react-native-camera';
import BarcodeMask from 'react-native-barcode-mask';
class ProductScanRNCamera extends Component {
constructor(props) {
super(props);
this.camera = null;
this.barcodeCodes = [];
this.showAlert = true;
this.state = {
camera: {
flashMode: RNCamera.Constants.FlashMode.auto,
}
};
}
onBarCodeRead = (e) => {
if (this.state.alertPresent) {
this.setState({ showAlert: false });
Alert.alert(
"Barcode type is " + e.type,
"Barcode value is " + e.data,
[
{ text: 'OK', onPress: () =>console.log('ok') },
],
{ cancelable: false },
);
}
}
pendingView() {
return (
<View
style={{
flex: 1,
backgroundColor: 'lightgreen',
justifyContent: 'center',
alignItems: 'center',
}}
>
<Text>Waiting</Text>
</View>
);
}
render() {
return (
<View style={styles.container}>
<RNCamera
ref={ref => {
this.camera = ref;
}}
defaultTouchToFocus
flashMode={this.state.camera.flashMode}
mirrorImage={false}
onBarCodeRead={this.onBarCodeRead.bind(this)}
onFocusChanged={() => { }}
onZoomChanged={() => { }}
style={styles.preview}
>
<BarcodeMask />
</RNCamera>
</View>
);
}
}

Related

How to handle volumes of multiple track in react-native sound, i want to play 2 sound together and if i want to decrease sound of one

Here is my code screen code
import React, {Component} from 'react';
import {StyleSheet, Text, TouchableOpacity, View, ScrollView, Alert} from 'react-native';
import Sound from 'react-native-sound';
import BgSoundPlayer from '../../../../Components/BgSoundPlayer/BgSoundPlayer';
const audioTests = [
{
title: 'mp3 remote download',
url: 'https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3',
},
{
title: "mp3 remote - file doesn't exist",
url: 'https://www.soundhelix.com/examples/mp3/SoundHelix-Song-9.mp3',
},
];
const Button = ({title, onPress}) => (
<TouchableOpacity onPress={onPress}>
<Text style={styles.button}>{title}</Text>
</TouchableOpacity>
);
const Header = ({children, style}) => <Text style={[styles.header, style]}>{children}</Text>;
const Feature = ({
title,
onPress,
buttonLabel = 'PLAY',
status,
volumeIncrease,
volumeDecrease,
}) => (
<View style={styles.feature}>
<Header style={{flex: 1}}>{title}</Header>
{status ? <Text style={{padding: 5}}>{resultIcons[status] || ''}</Text> : null}
<Button title={buttonLabel} onPress={onPress} />
<Button title="Volume Increase" onPress={volumeIncrease} />
<Button title="volume Decrease" onPress={volumeDecrease} />
</View>
);
const resultIcons = {
'': '',
pending: '?',
playing: '\u25B6',
win: '\u2713',
fail: '\u274C',
};
function setTestState(testInfo, component, status) {
component.setState({tests: {...component.state.tests, [testInfo.title]: status}});
}
/**
* Generic play function for majority of tests
*/
function playSound(testInfo, component) {
setTestState(testInfo, component, 'pending');
BgSoundPlayer.setSound(testInfo);
}
class MainView extends Component {
constructor(props) {
super(props);
Sound.setCategory('Playback', true); // true = mixWithOthers
// Special case for stopping
this.stopSoundLooped = () => {
if (!this.state.loopingSound) {
return;
}
this.state.loopingSound.stop().release();
this.setState({
loopingSound: null,
tests: {...this.state.tests, ['mp3 in bundle (looped)']: 'win'},
});
};
this.state = {
loopingSound: undefined,
tests: {},
};
}
render() {
return (
<View style={styles.container}>
<ScrollView style={styles.container} contentContainerStyle={styles.scrollContainer}>
{audioTests.map(testInfo => {
return (
<Feature
status={this.state.tests[testInfo.title]}
key={testInfo.title}
title={testInfo.title}
onPress={() => {
playSound(testInfo, this);
}}
volumeIncrease={() => {
BgSoundPlayer.increaseVolume();
}}
volumeDecrease={() => {
BgSoundPlayer.decreaseVolume();
}}
/>
);
})}
<Feature
title="mp3 in bundle (looped)"
buttonLabel={'STOP'}
onPress={() => {
BgSoundPlayer.pouse();
}}
/>
</ScrollView>
</View>
);
}
}
export default MainView;
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'gray',
},
scrollContainer: {},
title: {
fontSize: 20,
fontWeight: 'bold',
paddingTop: 30,
padding: 20,
textAlign: 'center',
backgroundColor: 'rgba(240,240,240,1)',
},
button: {
fontSize: 20,
backgroundColor: 'rgba(220,220,220,1)',
borderRadius: 4,
borderWidth: 1,
borderColor: 'rgba(80,80,80,0.5)',
overflow: 'hidden',
padding: 7,
},
header: {
textAlign: 'left',
},
feature: {
padding: 10,
borderTopWidth: 1,
borderBottomWidth: 1,
},
});
And my BgSoundPlayer file
import {Alert} from 'react-native';
import Sound from 'react-native-sound';
Sound.setCategory('Playback', true);
class BgSoundPlayer1 {
setSound(soundURL) {
try {
this.soundURL = soundURL;
if (soundURL.isRequire) {
this.soundRef = new Sound(soundURL.url, error =>
this.callback(error, this.soundRef),
);
} else {
this.soundRef = new Sound(soundURL.url, Sound.MAIN_BUNDLE, error =>
this.callback(error, this.soundRef),
);
}
} catch (error) {
console.log('SOUNDREFERROR::', error);
}
}
callback(error, sound) {
try {
if (error) {
Alert.alert('error', error.message);
return;
}
//this.soundURL.onPrepared && this.soundURL.onPrepared(sound);
sound.play(() => {
sound.release();
});
} catch (error) {
console.log('CALL_BACKERROR::', error);
}
}
getVolume() {
return this.soundRef?.getVolume();
}
increaseVolume(soundURL) {
console.log('CHECKREF', this.soundRef);
let sound = this.soundRef?.getVolume();
if (sound < 1 || sound == 1) {
this.soundRef?.setVolume(sound + 0.1);
}
}
decreaseVolume(soundURL) {
console.log('CHECKREF', this.soundRef);
let sound = this.soundRef?.getVolume();
if (sound > 0 || sound == 0) {
this.soundRef?.setVolume(sound - 0.1);
}
}
pouse() {
this.soundRef?.pause();
}
}
const BgSoundPlayer = new BgSoundPlayer1();
export default BgSoundPlayer;
So what is happening right now if, when I am playing one audio track and increasing decreasing volume of track its working fine
but problem occurre's when I play second track and decrease sound of first one, it dosent works it decrease volume of second track
but when I tried to debug problem, I got to know that my this.soundRef variable is taking the refrance of latest one sound, so how can solve this

ReferenceError: Can't find variable: state

I'm recording an app that records exercise logs.
If I click on the area,
I'd like to have items that correspond to that area on the screen.
import React, { Component } from "react";
import {
TouchableOpacity,
StyleSheet,
Text,
View,
FlatList,
} from "react-native";
let clickmenu = "";
class TouchableText extends Component {
render() {
clickmenu = this.props.children.item;
return (
<TouchableOpacity style={styles.text} onPress={this.props.press}>
<Text style={styles.text}>{this.props.children.item.toString()}</Text>
</TouchableOpacity>
);
}
}
class Detail extends Component {
state = {
data: {
chest: [
"플랫 벤치프레스",
"인클라인 벤치프레스",
"케이블 크로스오버",
"푸쉬업",
"딥스",
],
back: ["바벨로우", "데드리프트", "턱걸이", "씨티드 로우", "렛풀 다운"],
},
menu: [
"chest",
"back",
"legs",
"shoulder",
"biceps",
"triceps",
"abs",
"etc..",
],
isclicked: true,
};
press = () => {
this.setState({
isclicked: false,
});
};
render() {
const { data, menu, isclicked } = this.state;
return isclicked ? (
<View style={styles.container}>
<FlatList
data={this.state.menu.map((mp) => {
return mp;
})}
renderItem={(item) => (
<TouchableText press={this.press}>{item}</TouchableText>
)}
/>
</View>
) : (
<View>
{" "}
{(function () {
console.log(this);
if (clickmenu == "가슴") {
<FlatList
data={this.state.data.가슴.map((mp) => {
return mp;
})}
renderItem={(item) => <TouchableText>{item}</TouchableText>}
keyExtractor={(item, index) => index.toString()}
/>;
} else if (state.clickmenu == "등") {
<FlatList
data={this.state.data.등.map((mp) => {
return mp;
})}
renderItem={(item) => <TouchableText>{item}</TouchableText>}
/>;
} else {
console.log("world");
}
})()}
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "black",
},
text: { flex: 1, backgroundColor: "white", fontSize: 36, color: "black" },
});
export default Detail;
If I click on the chest button, The following error occurs:
function(){if(){}}
Does this mean class detail in ? How should I solve this?
You are missing a this.
Change
} else if (state.clickmenu == "등") {
to
} else if (this.state.clickmenu == "등") {
You need to set up a constructor with your state attributes within it as such:
class Detail extends Component {
constructor(props) {
super(props);
this.state = {
isLoading: true,
stateAttributesHere: "",
};
}
...
...
}
else if (state.clickmenu == "등") => else if (clickmenu == "등")

How to run a funtion onclick of button from one component and funtion run on another compoenent in react native

Code of Home.js
import React, { Component } from 'react'
import { Text, View, Alert } from 'react-native'
import { Card, Title, Paragraph, Button } from 'react-native-paper';
import Animater from '../component/Animater'
import FontAwesome5 from 'react-native-vector-icons/FontAwesome5';
import { act } from 'react-test-renderer';
const data = [
{
id: 1,
q: "Is you age above 50 or below 10",
uri: 'https://miro.medium.com/max/524/1*Peqrh5C9f4lSNNBiwguxTw.png',
},
{
id: 2,
q: "Do You Visited Forign before 15 March?",
uri: 'https://www.howitworksdaily.com/wp-content/uploads/2015/07/68_1.jpg'
},
...
{
id: 9,
q: "Do you meet any Foreigner or NRI",
uri: 'https://assets3.thrillist.com/v1/image/2079046/size/tmg-article_default_mobile_2x.jpg',
}
]export default class CheckCorona extends Component {
constructor(props){
super(props)
}
ButtonPressed=()=>{
console.log("yess it is working")
}
renderCard(item) {
return (
<View key={item.id}>
<Card>
<Card.Content>
<Title style={{ marginHorizontal: 15, fontSize: 24 }}>Q{item.id}: {item.q}</Title>
<Card.Cover source={{ uri: item.uri }} />
<Card.Actions>
<Button onPress={()=>this.ButtonPressed()} >Yess</Button>
<Button>No</Button>
</Card.Actions>
</Card.Content>
</Card>
</View>
)
}
ShowResult = () => {
return (
<Card>
<Title>Tu Single is thik hai</Title>
</Card>
)
}
render() {
return (
<View>
<Animater
data={data}
renderCard={this.renderCard}
ShowResult={this.ShowResult}
ButtonPressed={this.ButtonPressed}
/>
</View>
)
}
}
and Code of Animate.js is
import React, { Component } from 'react'
import { Text, View, PanResponder, Animated, Dimensions, StyleSheet, Alert } from 'react-native'
const Screen_width = Dimensions.get('window').width;
const Swipe_Limit = Screen_width / 2;
export default class Animater extends Component {
constructor(props) {
super(props)
this.state = {
index: 0
}
const position = new Animated.ValueXY();
this.PanResponder = PanResponder.create({
onStartShouldSetPanResponder: () => true,
onPanResponderMove: (e, gesture) => {
position.setValue({ x: gesture.dx, y: gesture.dy })
},
onPanResponderRelease: (e, gesture) => {
if (gesture.dx > Swipe_Limit) {
this.swipe("right")
} else if (gesture.dx < -Swipe_Limit) {
this.swipe("Left")
} else {
this.resetPosition()
}
}
})
this.position = position
}
DoSwiable = () => {
// const newCheck= 'this.swipe("right")'
if(this.props.ButtonPressed()){
console.log("hello")
}
}
swipe = (direction) => {
const x = direction === 'right' ? Screen_width * 3 : -Screen_width * 3
Animated.timing(this.position, {
toValue: { x: x, y: 0 }
}).start(() => {
this.position.setValue({ x: 0, y: 0 }),
this.setState({
index: this.state.index + 1
})
})
}
resetPosition = () => {
Animated.spring(this.position, {
toValue: { x: 0, y: 0 }
}).start()
}
mycardstyle = () => {
const rotate = this.position.x.interpolate({
inputRange: [-Screen_width, 0, Screen_width],
outputRange: ['-120deg', '0deg', '120deg']
})
return {
...this.position.getLayout(),
transform: [{ rotate: rotate }]
}
}
rendercard = () => {
if (this.state.index >= this.props.data.length) {
return this.props.ShowResult()
}
return this.props.data.map((item, i) => {
if (i < this.state.index) {
return null
}
if (i === this.state.index) {
return (
<Animated.View key={i}
style={[this.mycardstyle(), styles.cardStyle]}
{...this.PanResponder.panHandlers}>
{this.props.renderCard(item)}
</Animated.View>
)
}
return (
<View key={item.id} style={[styles.cardStyle, { top: 5 * (i - this.state.index) }]}>
{this.props.renderCard(item)}
</View>
)
}).reverse()
}
render() {
return (
<View>
{this.rendercard()}
</View>
)
}
}
const styles = StyleSheet.create({
cardStyle: {
position: "absolute",
zIndex: 1,
width: Screen_width
}
})
Actually it is swipeable card I want that when Yes button on Home.js pressed then function on animated.js should run this.swipe("right")
Actually I have used props for the showing the data and so the main screen is Home.js and I have import the Animater.js and pass some function is a props and then I am running the props.
Change
ButtonPressed=()=>{
console.log("yess it is working")
}
to
ButtonPressed=()=>{
console.log("yess it is working");
(new Animater()).swipe("right");
}
Hope this helps you!

Function not being passed to child component

I am a learner in react native, any help will go a great mile :), I started using react-navigation for my app, I have a child component as the header of my parent component, This child component contains a <TextInput/> I want to update the parent component on change of the child component's TextInput, normally passing down a function as the value of the props will work, But since I am using static navigationOptions to access the child component, that won't work, I have to set the navigation.params.state, I have done this, I have read through documentations, I looked through this link https://github.com/react-navigation/react-navigation/issues/147 But it always comes back with this error undefined is not an object(evaluating 'params.update')
Please how can I make this work and pass the function successfully to the Box component
BOX COMPONENT
class Box extends React.Component {
constructor(props) {
super(props);
this.state = {
search: ""
}
}
handleChange = (e) => {
this.props.onUpdate(e.target.value);
this.setState({search: e.target.value});
}
render() {
return (
<TextInput placeholder="Search for your herbs by name,type..." value={this.state.search}
onChange={this.handleChange}
underlineColorAndroid={'transparent'}
style={BackStyles.textBox}/> ); }}
HOME COMPONENT
export default class Home extends React.Component {
onUpdate = (val) => {
this.setState({
search: val
});
let db = SQLite.openDatabase({
name: 'test.db',
createFromLocation: "~Herbo.db",
location: 'Library'
}, this.openCB, this.errorCB);
db.transaction((tx) => {
tx.executeSql("SELECT * FROM data where name like '" + this.state.search + "' ", [], (tx, results) => {
console.log("Query completed");
var len = results.rows.length;
for (let i = 0; i < len; i++) {
let row = results.rows.item(i);
this.setState(prevState => ({
record: [...prevState.record, row],
pressed: [...prevState.pressed, false]
}));
console.log(`Record: ${row.name}`);
//this.sleep(2);
//this.setState({record: row});
}
this.setState({loader: false})
});
});
};
static navigationOptions = ({navigation}) => {
const {params} = navigation.state.params || {};
return {
headerTitle: <Box onUpdate={params.update}/>,
};
// header: null
};
componentDidMount() {
this.navigation.setParams({
update: this.props.onUpdate()
})
}
constructor(props) {
super(props);
this.state = {
record: [],
header: null,
loader: true,
pressed: {},
ar: [],
search: ''
};
let db = SQLite.openDatabase({
name: 'test.db',
createFromLocation: "~Herbo.db",
location: 'Library'
}, this.openCB, this.errorCB);
db.transaction((tx) => {
tx.executeSql('SELECT * FROM data', [], (tx, results) => {
console.log("Query completed");
var len = results.rows.length;
for (let i = 0; i < len; i++) {
let row = results.rows.item(i);
this.setState(prevState => ({
record: [...prevState.record, row],
pressed: [...prevState.pressed, false]
}));
console.log(`Record: ${row.name}`);
//this.sleep(2);
//this.setState({record: row});
}
this.setState({loader: false})
});
});
}
handlePressedIn = (i, value) => {
if (this.state.ar.length > 0) {
this.state.ar.map((value) => {
this.setState(prevState => {
const pressed = {...prevState.pressed};
pressed[value] = false;
return {pressed};
})
});
}
this.setState(prevState => {
if (!this.state.ar.includes(i)) {
this.setState(prevState => ({
ar: [...prevState.ar, i]
}));
}
const pressed = {...prevState.pressed};
pressed[i] = !pressed[i];
return {pressed};
});
this.props.navigation.navigate('Details', {
itemId: i + 1,
otherParam: value
});
};
errorCB(err) {
console.log("SQL Error: " + err);
}
successCB() {
console.log("SQL executed fine");
}
openCB() {
console.log("Database OPENED");
}
render() {
const herbs = this.state.record.map((herb) =>
<TouchableNativeFeedback onPress={() => this.handlePressedIn(herb.id - 1, herb.name)} key={herb.id}>
<View style={this.state.pressed[herb.id - 1] ? BackStyles.herbBox : BackStyles.herb_box}>
<Image style={BackStyles.image} source={{uri: `${herb.name.replace(/ /g, '')}`}}/>
<View style={{flexDirection: 'column',}}><Text
style={this.state.pressed[herb.id - 1] ? BackStyles.header2 : BackStyles.header}>{herb.name}</Text>
<Text
style={this.state.pressed[herb.id - 1] ? BackStyles.sub2 : BackStyles.sub}>{herb.bot}</Text></View>
</View></TouchableNativeFeedback>
);
const view = <ScrollView overScrollMode={'never'}>{herbs}</ScrollView>;
return (
<View style={BackStyles.main}>
<View style={{flex: 1}}>
{
this.state.loader ?
<ActivityIndicator animating={this.state.loader} color='#28B564' size="large"
style={BackStyles.activityIndicator}/> : <View>{view}</View>
} </View></View> ); }}
APP.js(Main Component)
import Splash from './components/Splash';
import {createStackNavigator} from 'react-navigation';
const RootStack = createStackNavigator(
{
Home: {
screen: Home,
},
Details: {
screen: Details,
},
},
{
initialRouteName: 'Home',
navigationOptions: {
headerStyle: {
backgroundColor: '#fff',
},
headerTintColor: '#28B564',
headerTitleStyle: {
fontWeight: 'bold',
},
},
}
);
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
timePassed: false,
};
}
render() {
setTimeout(() => {
this.setState({timePassed: true})
}, 4000);
if (!this.state.timePassed) {
return <View style={{flex: 1}}>
<StatusBar backgroundColor='#28B564' barStyle='light-content'/><Splash/></View>;
} else {
return (<View style={{flex: 1}}>
<StatusBar backgroundColor='#28B564' barStyle='light-content'/>
<RootStack/></View>
);} }}

How to have multiple Flatlists with filtered data in React Native

How do I create multiple Flatlists that only present data with one type of 'status'?
For example:
One Flatlist for status === 'inProgress'
One Flatlist for status ===
'Done'
One Flatlist for status ===
'Failed'
All data is in the array ‘goallist’, which comes from a Firebase database.
I would really appreciate your help with this.
import React, { Component } from 'react';
import { Text, FlatList, View, Image, TouchableOpacity, Alert } from 'react-native';
import firebase from 'firebase';
import { Button, Card, CardSection } from '../common';
import styles from '../Styles';
class List extends Component {
static navigationOptions = {
title: 'List',
}
constructor(props) {
super(props);
this.state = {
goallist: '',
loading: false,
};
}
componentDidMount() {
this.setState({ loading: true });
const { currentUser } = firebase.auth();
const keyParent = firebase.database().ref(`/users/${currentUser.uid}/goalProfile`);
keyParent.on(('child_added'), snapshot => {
const newChild = {
key: snapshot.key,
goal: snapshot.val().goal,
status: snapshot.val().status
};
this.setState((prevState) => ({ goallist: [...prevState.goallist, newChild] }));
console.log(this.state.goallist);
});
this.setState({ loading: false });
}
onRenderItem = ({ item }) => (
<TouchableOpacity onPress={this.showAlert}>
<Text style={styles.listStyle}>
{ item.goal } { item.key }
</Text>
</TouchableOpacity>
);
showAlert = () => {
Alert.alert(
'Did you succeed or fail?',
'Update your status',
[
{ text: 'Completed?',
onPress: () => console.log('Completed Pressed'), },
{ text: 'Failed?',
onPress: () => console.log('Failed Pressed'),
},
{ text: 'Cancel',
onPress: () => console.log('Cancel Pressed'),
style: 'cancel' },
],
{ cancelable: false }
);
}
keyExtractor = (item) => item.key;
render() {
return (
<Card>
<View style={{ flex: 1 }}>
<FlatList
data={this.state.goallist}
keyExtractor={this.keyExtractor}
extraData={this.state}
renderItem={this.onRenderItem}
/>
</View>
</Card>
);
}
}
export { List };
You just need to modify your onRenderItem function to render some specific objects as below (this Flatlist shows only inProgress objects):
onRenderItem = ({ item }) => {
if (item.type === 'inProgress') {
return (
<TouchableOpacity onPress={this.showAlert}>
<Text style={styles.listStyle}>
{ item.goal } { item.key }
</Text>
</TouchableOpacity>
)
} else { return null; }
};

Categories

Resources