How to capture videos with react-native-camera module? - reactjs

I can capture pictures with this module without any problem, but when I try to record video, I can't seem to find where the recorded video is (or maybe no video was even recorded at all). Here is my CameraScreen:
import Camera from 'react-native-camera';
const { CaptureMode, CaptureTarget } = Camera.constants;
const { video: captureModeVideo, still: captureModePhoto } = CaptureMode;
class CameraScreen extends Component {
constructor(props) {
super(props);
this.state = {
captureMode: captureModePhoto,
isRecording: false
};
this.onCapture = this.onCapture.bind(this);
this.onSwitchCaptureMode = this.onSwitchCameraMode.bind(this);
}
onCapture() {
const { captureMode, isRecording } = this.state;
if (isRecording) {
this._camera.stopCapture();
this.setState({ isRecording: false });
return;
}
if (captureMode === captureModeVideo) {
this.setState({ isRecording: true });
}
this._camera.capture({ mode: captureMode })
.then((result) => console.log(result))
.catch((error) => console.log(error));
}
onSwitchCaptureMode() {
if (this.state.captureMode === captureModeVideo) {
this.setState({ captureMode: captureModePhoto });
} else {
this.setState({ captureMode: captureModeVideo });
}
}
render() {
const { captureMode } = this.state;
return (
<Camera
ref={(ref) => this._camera = ref}
style={{ flex: 1 }}
captureMode={captureMode}
captureTarget={CaptureTarget.disk}
>
<TouchableOpacity onPress={this.onCapture}>
<Icon
name='camera-alt'
...
...
/>
</TouchableOpacity>
<TouchableOpacity onPress={this.onSwitchCaptureMode}>
<Icon
name='...'
...
...
/>
</TouchableOpacity>
</Camera>
);
}
}
export default CameraScreen;
When I'm taking photos, the console.log(result) statement logs the path of the photo without a problem, but when captureMode === captureModePhoto, I don't have any logs in my debugger, is there something I'm doing wrong? I omitted many stylings to make the code more understandable

This is a silly mistake
The code posted by me works absolutely fine, but I have to test it on a real device. A simulator supports taking images (it generates some image with a random background color), but doesn't support taking videos. Therefore, problem solved

Related

How I do use fetch API and store response in the state?

I have to get a file from the server, After the component is rendered, that contains information from cities, and I must assign it to "citiesData" in the state. But the data is not received because it is not seen in the output.
what is the issue with my fetch?
server file:
IranMap(the file seems to have a problem in fetch):
import React from 'react';
import './IranMap.css';
import CityModal from './CityModal';
class IranMap extends React.Component {
state = {
error: null,
citiesData: null,
selectedCity: null,
isModalOpen: false,
};
componentDidMount() {
fetch('http://localhost:9000/cities')
.then(response => response.json())
.then((result) => {
this.setState({
citiesData: result
});
},
(error) => {
this.setState({
error
});
}
)
}
cityClicked = (id) => (event) => {
event.preventDefault();
fetch(`http://localhost:9000/cities/${id}`,{method: 'GET'})
.then(res => res.json())
.then(result => {
this.setState({
selectedCity: result,
isModalOpen: true
});
})
}
closeModal = () => {
this.setState({
isModalOpen: false,
});
};
render() {
if(this.state.error){
return <div>Error: {this.state.error.message}</div>;
}
else {
return (
<div>
<div className="map-container">
{(this.state.citiesData || []).map((record) => (
<div
key={record.id}
className="city-name"
style={{
top: `${record.top}%`,
left: `${record.left}%`,
}}
onClick={this.cityClicked(record.id)}
>
{record.name}
</div>
))}
</div>
<CityModal
city={this.state.selectedCity}
isOpen={this.state.isModalOpen}
onClose={this.closeModal}
/>
</div>
);
}
}
}
export default IranMap;
This is my output. it should be show cities name. but this is empty:
I think what you are trying to do is render the entire object,u cant do that, try the render each element, The second part of my answer is that you should use an asynchronous task.
I hope my answer guided you

activate async function on load screen

Im trying to create a users list with my api using a async function, but I dont know how to user it on load screen, can you help me
export default class Dermatologistas extends Component{
state ={
errorMessage: null,
users: []
}
getUserList = async () => {
try {
const response = await api.get('/auth/list');
const { users } = response.data
console.log(response.data)
this.setState({ users });
} catch (response) {
this.setState({ errorMessage: response.data.error });
}
};
render(){
const users = this.state.users
console.log(users)
return(
<View >
how you can see I was using a button to load everything, but i wanted to load when the screen loads
<Button onPress={this.getUserList} title='carregar'/>
{this.state.users.map(user => (
<View key={user._id} style={{marginTop: 15, alignItems: 'center'}}>
<Text>{user.title}</Text>
<Text>{user.speciality}</Text>
<Button title = 'View Profile'onPress ={() => this.props.navigation.navigate('Profile')}/>
</View>
))}
</View>
)
}
}
componentDidMount() {
this.getUserList();
}

How to display user specific data from firebase as a FlatList in React Native

I'm new to reactnative and firebase and i looked for any infomation on this but had no luck in figuring out how to do this. Basically i want to display data from firebase which is specific to the user currently logged in, ive gotten halfway thru but don't understand what to do next. can someone show me what the rest of the code needs to be
Heres my code:
class HomeScreen extends Component {
constructor() {
super();
this.state = {
uid: ''
}
}
readUserData() {
currentUser = firebase.auth().currentUser
var that = this
firebase.database().ref(`BorrowedBooks`).child(currentUser.uid).on('value', function (data) {
console.log(data.val())
});
}
signOut = () => {
firebase.auth().signOut().then(() => {
this.props.navigation.navigate('Login')
})
.catch(error => this.setState({ errorMessage: error.message }))
}
render() {
this.state = {
displayName: firebase.auth().currentUser.displayName,
uid: firebase.auth().currentUser.uid
}
return (
<View style={styles.container}>
<Text style = {styles.textStyle}>
Hello, {this.state.displayName}
</Text>
<View>
<FlatList/>
</View>
<Button
color="#3740FE"
title="Logout"
onPress={() => this.signOut()}
/>
<Button
color="#3740FE"
title="display books"
onPress={this.readUserData}
/>
</View>
);
}
}
This is what my firebase database looks like: firebase database
This is the response after console.log: console.log output
you need to store the data in an array before you can display it in FlatList
readUserData() {
currentUser = firebase.auth().currentUser
var that = this
firebase.database().ref(`BorrowedBooks`).child(currentUser.uid).on('value', function (data) {
//console.log(data.val())
let DATA = [];
if(data.exists()){
KEY = Object.keys(data.val());
KEY.forEach( (key_id) => {
let a = snapshot.val()[key_id];
a.key = key_id;
DATA.push(a);
})
that.setState({userData: DATA})
});
}
then you can display it in flatlist
<FlatList
data = {this.state.userData}
renderItem ={({item}) =>
//render Items here
}
/>

Refresh screen or component when navigate to it

I have two screens, one for displaying the records consuming an API and the other for registering.
the problem is that when I do a register and navigate to the display screen it does not update.
This is a construction of the screen:
constructor(props) {
super(props);
this.state = {isLoading: true, pendIsLoading: true, dataSource: [], contentStorageS:""}
};
fetchDados = async () => {
let usuario = await AsyncStorage.getItem("ASCOFAR_app_usuario");
try {
const response = await api.get("api/listaRegistros.php?usuario="+usuario);
const responseData = await response.data
if(responseData.status == "ERRO"){
this.setState({
isLoading: false,
dataSource: "",
})
}else{
this.setState({
isLoading: false,
dataSource: responseData,
})
}
console.log(response)
} catch (error) {
Alert.alert(error)
}
}
async componentDidMount () {
this.fetchDados();
this.atualizaState();
}
tirarLoad() {
if(this.state.isLoading == true){
return (
<ActivityIndicator size="large" color="#be152c"/>
)
}else if(this.state.dataSource == ""){
return (
<ScrollView >
<View style={{justifyContent:"center", alignItems:"center",}}>
<Image
style ={{width:150, height:150, marginTop:35}}
source={require('../assets/images/aguardando.png')}
/>
</View>
</ScrollView>
)
}else{
return (
<ScrollView>
<Text style={styles.tituloGrid}>Formularios Enviados</Text>
{this.state.dataSource.map(dados => (
<View style={styles.list} key={dados.id}>
<Text style={styles.listChild}>{dados.id}</Text>
<Text style={styles.listChild}>{dados.nome}</Text>
<Text>|</Text>
<Text style={styles.listChild}>{dados.endereco}</Text>
</View>
))}
</ScrollView>
)
}
}
<View style={styles.grid}>
{this.tirarLoad()}
</View>
I need to know how to do when navigating to this screen to update API consumption
Assuming you are using React-Navigation, did you try to addListener
focus react-navigation documentation
You could also do it by componentDidUpdate. I could not find the official documentation for doing it on 5.x. I believe it still works with 5.x. (Doc on 3.x)
import { withNavigationFocus } from "react-navigation";
componentDidUpdate(prevProps) {
if (prevProps.isFocused !== this.props.isFocused) {
this.fetchDados()
//or other similar onFocus function
}
}
export default withNavigationFocus(TabScreen);
Try re-rendering your Home screen after navigation
this.props.navigation.navigate('Home', {
onBack: () => this.refresh() //function to refresh screen,
});
import { withNavigationFocus } from "react-navigation";
this.willFocusSubscription = this.props.navigation.addListener(
'willFocus',
() => {
this.refreshFetch();
this.refreshLocal();
}
);
componentWillUnmount() {
this.willFocusSubscription.remove();
}

Can I subscribe to this.props.navigation.state.params?

I am wonder if in screenA I have an object data = {} that will be changed dynamically, can I receive changes in screenB by just sending this props from screenA through this.props.navigation.navigate('screenB', {data})?
And in screenB to have a componentWillReceiveProps(nextProps) to get this changes through something like nextProps.navigation.state.param.data
Or there is a way to achieve this?
You can use onWillFocus of NavigationEvents, which fires whenever the screen is navigated to.
_willFocus = () => {
const { navigation } = this.props
const data = navigation.getParam('data', null)
if (data !== null) {
/* do something */
}
}
/* ... */
render () {
return (
<View>
<NavigationEvents onWillFocus={_willFocus()}
</View>
)
}
It is easy, just as you said: send some data navigation.navigate('screenB', { data }) and receive it in the screenB as navigation.state.params.data.
I agree with #FurkanO you probably show use Redux instead to control all the state of your app, but for simple stuff I think isn't necessary!
I made a simple snack demo to show you: snack.expo.io/#abranhe/stackoverflow-56671202
Here some code to follow up:
Home Screen
class HomeScreen extends Component {
state = {
colors: ['red', 'blue', 'green'],
};
render() {
return (
<View>
{this.state.colors.map(color => {
return <Text>{color}</Text>;
})}
<View>
<Text>Details Screen</Text>
<Button
title="Go to Details"
onPress={() => this.props.navigation.navigate('Details', { colors: this.state.colors })}
/>
</View>
</View>
);
}
}
Details Screen
class DetailsScreen extends Component {
state = {
colors: [],
};
componentWillMount() {
this.setState({ colors: this.props.navigation.state.params.colors });
}
render() {
return (
<View>
{this.state.colors.map(color => {
return <Text>{color}</Text>;
})}
<Text>Details Screen</Text>
</View>
);
}
}
Update
The question's author requested an update to add a setTimeout() to see the exact moment when the data is on the other screen, so it will look like this:
componentWillMount() {
setTimeout(() => {
this.setState({ colors: this.props.navigation.state.params.colors });
}, 3000);
}

Resources