How can I show the selected time in React Native - react-native

First of all, hello everyone. This is my first question.
I'm trying to use time picker in React Native. I installed the package from the repo on GitHub. But I couldn't display the time in the text component? How can I do?
const Example = (props) => {
const [isDatePickerVisible, setDatePickerVisibility] = useState(false);
const showDatePicker = () => {
setDatePickerVisibility(true);
};
const hideDatePicker = () => {
setDatePickerVisibility(false);
};
const handleConfirm = (date) => {
console.warn("A date: ", date);
settimeShow(date)
hideDatePicker();
};
return (
<View>
<Button title="Show Time Picker" onPress={showDatePicker} />
<Text>
?
</Text>
<DateTimePickerModal
isVisible={isDatePickerVisible}
mode="time"
onConfirm={handleConfirm}
onCancel={hideDatePicker}
/>
</View>
);
};
enter image description here
https://github.com/mmazzarolo/react-native-modal-datetime-picker

You could use moment to format your time and then display it ,
moment(date).format('LT') /// example : 8:30 PM

your can get Date text in parameter date . in handleConfirm save date in one state and show it in Text :)
import React, { Component } from "react";
import { Button, View } from "react-native";
import DateTimePicker from "react-native-modal-datetime-picker";
export default class DateTimePickerTester extends Component {
constructor(props) {
super(props);
this.state = {
isDateTimePickerVisible: false,
selectedDate:'',
};
}
showDateTimePicker = () => {
this.setState({ isDateTimePickerVisible: true });
};
hideDateTimePicker = () => {
this.setState({ isDateTimePickerVisible: false });
};
handleDatePicked = date => {
console.log("A date has been picked: ", date);
setstate({selectedDate:date});
this.hideDateTimePicker();
};
render() {
return (
<>
<Button title="Show DatePicker" onPress={this.showDateTimePicker} />
<Text>this.state.selectedDate</Text>
<DateTimePicker
isVisible={this.state.isDateTimePickerVisible}
onConfirm={this.handleDatePicked}
onCancel={this.hideDateTimePicker}
/>
</>
);
}
}

Related

Expo : I want to render a Modal every x minutes

I want to render A modal every X minutes , so i tried to cache a value in AsyncStorage that gets removed every x minutes , and depends on the value i want to render the modal , but when my app is refreshed the modal appears again , here's what i have done :
import AsyncStorage from "#react-native-async-storage/async-storage";
import moment from "moment";
const prefix = "cache";
const expiryInMinutes = 5;
const store = async (key, value) => {
try {
const item = {
value,
timestamp: Date.now(),
};
await AsyncStorage.setItem(prefix + key, JSON.stringify(item));
} catch (error) {
console.log(error);
}
};
const isExpired = (item) => {
const now = moment(Date.now());
const storedTime = moment(item.timestamp);
return now.diff(storedTime, "minutes") > expiryInMinutes;
};
const get = async (key) => {
try {
const value = await AsyncStorage.getItem(prefix + key);
const item = JSON.parse(value);
if (!item) return null;
if (isExpired(item)) {
await AsyncStorage.removeItem(prefix + key);
return null;
}
return item.value;
} catch (error) {
console.log(error);
}
};
export default {
store,
get,
};
Then i have this component that i want to render every X minutes :
import React, { Component } from "react";
import { Text, TouchableOpacity, StyleSheet, View } from "react-native";
import Modal from "react-native-modal";
import AsyncStorage from "#react-native-async-storage/async-storage";
import cache from "../utility/cache";
export default class PubGlobal extends Component {
state = {
visibleModal: "false",
};
componentDidMount() {
cache.get("shown").then(
this.setState({
visibleModal: "true",
})
);
}
_renderButton = (text, onPress) => (
<TouchableOpacity onPress={onPress}>
<View style={styles.button}>
<Text>{text}</Text>
</View>
</TouchableOpacity>
);
_renderModalContent = () => (
<View style={styles.modalContent}>
<Text>Hello! </Text>
{this._renderButton("Close", () =>
cache
.store("shown", "false")
.then(this.setState({ visibleModal: "false" }))
)}
</View>
);
isShown = async () => {
try {
const stored = await cache.get("shown");
this.setState({ visibleModal: stored });
console.log(this.state.visibleModal);
} catch (error) {
console.log(error);
}
};
render() {
return (
<View style={styles.container}>
{/* {this._renderButton("Default modal", () =>
this.setState({ visibleModal: "true" })
)} */}
{this.state.visibleModal && (
<Modal isVisible={this.state.visibleModal === "true"}>
{this._renderModalContent()}
</Modal>
)}
</View>
);
}
}
In componentDidMount, after getting the value, visibleModal is set to "true".
You should use the value you are getting when cache.get("shown") resolves.
componentDidMount() {
cache.get("shown").then(
this.setState({
visibleModal: "true",
})
);
}

react-native audio recorder not stopping

My record stop button isnt working when I'm clicking on the record start then the record stop button getting an error that says "Println needs a message". What do I need to change?
Also my state component for the timer also isnt updating any suggestion why?
The timer should change when i click the start record button and then clear out when i say stop
`import AudioRecorderPlayer, {
AVEncoderAudioQualityIOSType,
AVEncodingOption,
AudioEncoderAndroidType,
AudioSet,
AudioSourceAndroidType,
} from 'react-native-audio-recorder-player'
import React, { Component } from 'react'
import { View, Button, Text } from 'react-native'
import { Header, Divider } from 'react-native-elements'
class Record extends Component {
constructor(props) {
super(props);
this.state = {
isLoggingIn: false,
recordSecs: 0,
recordTime: '00:00:00',
currentPositionSec: 0,
currentDurationSec: 0,
playTime: '00:00:00',
duration: '00:00:00',
};
this.audioRecorderPlayer = new AudioRecorderPlayer();
this.audioRecorderPlayer.setSubscriptionDuration(0.09); // optional. Default is 0.1
}
onStartRecord = async () => {
const path = 'hello.m4a';
const audioSet = {
AudioEncoderAndroid: AudioEncoderAndroidType.AAC,
AudioSourceAndroid: AudioSourceAndroidType.MIC,
AVEncoderAudioQualityKeyIOS: AVEncoderAudioQualityIOSType.high,
AVNumberOfChannelsKeyIOS: 2,
AVFormatIDKeyIOS: AVEncodingOption.aac,
};
console.log('audioSet', audioSet);
const uri = await this.audioRecorderPlayer.startRecorder(path, audioSet);
this.audioRecorderPlayer.addRecordBackListener((e) => {
this.setState({
recordSecs: e.current_position,
recordTime: this.audioRecorderPlayer.mmssss(
Math.floor(e.current_position),
),
});
});
console.log(`uri: ${uri}`);
};
onStopRecord = async () => {
const result = await this.audioRecorderPlayer.stopRecorder();
this.audioRecorderPlayer.removeRecordBackListener();
this.setState({
recordSecs: 0,
});
console.log(result);
};
onStartPlay = async (e) => {
console.log('onStartPlay');
const path = 'sdcard/hello.m4a'
const msg = await this.audioRecorderPlayer.startPlayer(path);
this.audioRecorderPlayer.setVolume(1.0);
console.log(msg);
this.audioRecorderPlayer.addPlayBackListener((e) => {
if (e.current_position === e.duration) {
console.log('finished');
this.audioRecorderPlayer.stopPlayer();
}
this.setState({
currentPositionSec: e.current_position,
currentDurationSec: e.duration,
playTime: this.audioRecorderPlayer.mmssss(
Math.floor(e.current_position),
),
duration: this.audioRecorderPlayer.mmssss(Math.floor(e.duration)),
});
});
};
onPausePlay = async (e) => {
await this.audioRecorderPlayer.pausePlayer();
};
onStopPlay = async (e) => {
console.log('onStopPlay');
this.audioRecorderPlayer.stopPlayer();
this.audioRecorderPlayer.removePlayBackListener();
};
render() {
return (<View>
<Header>InstaPlayer</Header>
<Text>{this.state.recordTime}</Text>
<Button title="Record" onPress={() => this.onStartRecord()} />
<Button title="Stop"
onPress={() => this.onStopRecord()}
/>
<Text>{this.state.playTime} / {this.state.duration}</Text>
<Button title="PLAY" onPress={() => this.onStartPlay()} />
<Button
title="Pause"
onPress={() => this.onPausePlay()}
/>
<Button
title="Stop"
onPress={() => this.onStopPlay()}
/>
</View>)
}
}
export default Record`
From my experience this error seems to be happening when the recorder is not stopped properly in the previous run. If the recorder is stopped properly, this error doesn't occur for me.

How to setting state with navigation params?

I am working on a React-native project with its basic packets(navigation etc). I have two screens. First there is a button and when i click the button. It's navigate to another screen which has flatlist. Then i click value in flatlist it is gives me a value . I can send that value to first screen with this.props.navigation.navigate and i can show it in console but i dont know how to use it to change buttonText which in my first screen? Where should i use setstate function in first screen ? (sorry for english)
Home.js
import React, {Component} from 'react';
import {View, Text} from 'react-native';
import {InputWithButton} from '../components/TextInput';
//const TEMP_BASE_CURRENCY = 'USD';
//const TEMP_CONVERT_CURRENCY = 'GBP';
class Home extends Component {
constructor(props) {
super(props);
this.state = {
baseCurrency: 'TRY', //Başlangıç olarak sayfa açıldığında gelecek olan değerler
convertCurrency: 'USD',
amount: null,
result: '',
date: '',
};
//const selected = this.props.route.params;
}
calculate = () => {
const amount = this.state.amount;
let url =
'https://api.exchangeratesapi.io/latest?base=' + this.state.baseCurrency;
fetch(url, {
method: 'GET',
})
.then((res) => res.json())
.then((data) => {
const date = data.date;
const result = (
data.rates[this.state.convertCurrency] * amount
).toFixed(2);
this.setState({
result,
date,
});
})
.catch((error) => {
console.log(error);
});
};
handleChangeText = (text) => {
//Yazıda değişim algılandığında api işlemleri başlasın
this.setState(
{
amount: text,
},
this.calculate,
);
};
handlePressBaseCurrency = () => {
//flatlist sayfası açılsın
const {navigation} = this.props;
navigation.navigate('CurrencyList');
};
handlePressConvertCurrency = () => {
//flatlist sayfası açılsın
};
render() {
const {baseCurrency, convertCurrency, amount, result, date} = this.state;
return (
<View>
<InputWithButton
buttonText={baseCurrency}
onPress={this.handlePressBaseCurrency}
keyboardType="numeric"
onChangeText={(text) => this.handleChangeText(text)}
/>
<InputWithButton
editable={false}
buttonText={convertCurrency}
onPress={this.handlePressConvertCurrency}
value={result}
/>
</View>
);
}
}
export default Home;
CurrencyList.js
import React, {Component} from 'react';
import {View, FlatList, Text} from 'react-native';
import currencies from '../data/currencies';
import {ListItem, Separator} from '../components/List';
const temp_base_currency = 'CAD';
class CurrencyList extends Component {
constructor(props) {
super(props);
this.state = {
selectedItem: '',
};
}
handlePress = (item) => {
this.setState({
selectedItem: item, //__
});
// const {navigate} = this.props.navigation;
// navigate('Home', {clickedItem: this.state.selectedItem});
//Tıklandığında beklesin
setTimeout(
() => this.props.navigation.navigate('Home', {selected: item}),
1,
); //__
};
render() {
return (
<View>
<FlatList
renderItem={({item}) => (
<ListItem
onPress={() => this.handlePress(item)}
text={item}
selected={item === this.state.selectedItem} //__
/>
)}
data={currencies}
keyExtractor={(item) => item}
ItemSeparatorComponent={Separator}
/>
</View>
);
}
}
export default CurrencyList;
It would have been better if you shared your code but here is what I would do.
SECOND SCREEN
this.props.navigation.navigate('firstScreen', {
name: 'Your value'
})
FIRST SCREEN
const name = this.props.route.params.name;
<Button>{name}</Button
You can pass the selected item from the Flatlist to the Home screen like this:
Home.js:
this.props.navigation.navigate('CurrencyList',
{
onGoback: (item) => this.setState({})
})
CurrencyList.js:
handlePress: (item) => {
/** your code **/
this.props.navigation.state.params.onGoBack(item)
this.props.navigation.navigate('Home')
}

react native modal not close after setState false

I have set modal visibility to false but it still showing. I cant figure out what causes this issue. this my code at loading.js.
I'm use this component in main what happen when setState false but its just close after close simolator and restart the device
import React,{Component} from 'react';
import PropTypes from 'prop-types'
import {View, Image, Modal, StyleSheet, Text} from "react-native";
export default class Loader extends Component{
render(){
const {animationType,modalVisible}=this.props;
return(
<Modal
animationType={animationType}
transparent={true}
visible={modalVisible}>
<View style={styles.wrapper}>
<View style={styles.loaderContainer}>
<Image
source={require('../img/loading.gif')}
style={styles.loaderImage}/>
</View>
</View>
</Modal>
)
}
}
Loader.propTypes={
animationType:PropTypes.string.isRequired,
modalVisible:PropTypes.bool.isRequired
}
this main class
export default class ForoshRah extends Component {
constructor() {
super();
I18nManager.forceRTL(true);
this.state = {
image: null,
images: null,
loadingVisible:false,
};
this.onValueChange2=this.onValueChange2.bind(this);
this.OnSubmiteData=this.OnSubmiteData.bind(this);
}
onValueChange2(value: string) {
this.setState({
Field: value,
});
}
async OnSubmiteData(){
this.setState({loadingVisible:true})
let token = await AsyncStorage.getItem('token',token);
let response = await
fetch(url,{
method:'POST',
headers:{
'Content-Type':'application/json',
Authorization:'JWT'+" "+token,
}
,body: JSON.stringify({
title,
})
})
let register = await response.json();
this.setState({userID:register.id})
if(response.status===200){
this.UploadImage()
}
}
async UploadImage() {
let token = await AsyncStorage.getItem('token',token);
let response = await fetch(url,{
method:'POST',
headers:{
Authorization:'JWT'+" "+token,
},body: formData
})
let uimage = await response;
console.log('user',this.state.userID);
if(response.status=200){
handleCloseModal = () => {
console.log(this.state.loadingVisible);
this.setState({ loadingVisible: false})
});
};
this.props.navigation.dispatch({ type: 'Navigation/BACK' })
}else {
setTimeout(() => {
this.setState({ loadingVisible: false })
}, 100)
}
setTimeout(() => {
this.setState({ loadingVisible: false })
}, 100)
}
render() {
return (
<KeyboardAwareScrollView >
<View style={{marginBottom:'10%'}}>
<Button block style={{backgroundColor:'#8e25a0'}} onPress={this.OnSubmiteData.bind(this)}>
</Button>
</View>
<Loader
modalVisible={loadingVisible}
animationType="fade"
/>
</KeyboardAwareScrollView>
);
}
}
onsubmitdata setState true and after response going to 200 Setstate set false in code main
You cannot just call state name as you have did. You should do like below.
<Loader
modalVisible={this.state.loadingVisible}
animationType="fade"
/>

Jest test failing when i try to set a state

I am trying to write some tests for a component i have written. It is a date/time component where by when you set a date from a calender, it sets the date to its local state, and then moves to a time selection component.
While this all works perfectly as a component, i cant seem to get th tests to pass. Currently having a problem with setting state in a jest test.
The test is as follows:
it('Time picker should appear', () => {
const navigation = {
navigate: jest.fn(),
};
const output = shallow(<DateTimePicker navigation={navigation} />);
const date = new Date('January 31 2018 12:30');
output.setState({selectedDate: date});
expect(output).toMatchSnapshot();
});
code of component is as follows:
import React from 'react';
import { View } from 'react-native';
import { injectIntl, FormattedMessage } from 'react-intl';
import { DatePicker } from '../../components/DatePicker';
import TimePicker from '../../components/TimePicker';
import Text from '../../components/Text';
import { propTypes } from './prop-types';
import styles from './styles';
export class DateTimePicker extends React.Component {
state = {
selectedDate: '',
}
confirmDateAndTime = (hours, minutes) => {
const { selectedDate } = this.state;
const date = new Date(selectedDate);
date.setHours(hours);
date.setMinutes(minutes);
const { navigation } = this.props;
/**
* navigate back to booking flight edit with the updated
* date selection.
*/
navigation.navigate('BookingFlightEdit', date);
}
render() {
const { selectedDate } = this.state;
/**
* if date has been selected - move onto the time selection
*/
if(selectedDate.length>0) {
return (
<View>
<View>
<Text style={styles.title} type="h1">
<FormattedMessage
defaultMessage="Select Time"
id="date_time_picker.select_time"
/>
</Text>
</View>
<View style={styles.time}>
<TimePicker
testID='time-button'
onPress={(hh,mm) => this.confirmDateAndTime(hh, mm)}
/>
</View>
</View>
);
}
return (
<View>
<Text style={styles.title} type="h1">
<FormattedMessage
defaultMessage="Select Date"
id="date_time_picker.select_date"
/>
</Text>
<DatePicker
testID = 'date-button'
onDayPress={(date) => this.setState({selectedDate: date.dateString})}
/>
</View>
);
}
}
DateTimePicker.propTypes = propTypes;
export default injectIntl(DateTimePicker);
however, whenever i run the test, iget the following error;
ShallowWrapper::setState() can only be called on class components
Your class is wrapped by injectIntl. This is the direct cause of the error you're encountering, as the internals of injectIntl are not a class. You will want to test an instance of your DateTimePicker class that is not wrapped by this Higher-Order component. You can do this by calling .dive() on the Enzyme wrapper.
it('Time picker should appear', () => {
const navigation = {
navigate: jest.fn(),
};
const output = shallow(<DateTimePicker navigation={navigation} />);
const date = new Date('January 31 2018 12:30');
const datePicker = output.dive();
datePicker.setState({selectedDate: date});
expect(datePicker).toMatchSnapshot();
});