react native navigation via a button in a modal - react-native

In my application, I want to navigate to another screen from a button in a modal. I tried the normal workout and it didn't work. The modal closes properly but the navigation doesn't happen. What am I doing wrong here? Im trying to navigate from navigateToMainFeed() and it stays in the same screen without navigating.
class TrainerRegistraionScreen extends Component {
constructor(props) {
super(props);
this.state = {
statement: {
value: "",
valid: false,
touched: false,
validationRules: {
minLength: 1
}
},
keyboardVisible: false,
buttonTouched: false,
displayModal: false
}
}
// handle statement changes
statementChangedHandler = value => {
this.setState(prevState => {
return {
statement: {
...prevState.statement,
value: value,
touched: true,
valid: validate(value, prevState.statement.validationRules)
},
buttonTouched: false
};
});
};
// check for empty fields of the screen
_getFiledsNotEmptyStatus = () => {
return this.state.statement.value.length > 0 ? true : false;
}
// display message
_displayMessage = () => {
let { keyboardVisible } = this.state;
let content = (
<View style={{ width: "90%", marginBottom: 10, alignSelf: 'center' }}>
<Text style={{ fontSize: 16, color: "#707070", fontWeight: "300" }}>
Please write a short statement about your focuses as a trainer.
It is important to show your capabilities and knowledge base in
exercise and nutrition science. Inclue all certification details.
</Text>
</View>
);
if (keyboardVisible) {
content = null;
}
return content;
}
// navigate to main feed
navigateToMainFeed = () => {
this.props.navigation.navigate("mainfeed");
this.setState({
displayModal: false
});
}
// register trainer
async registerTrainer() {
let {
firstName,
lastName,
email,
password
} = this.props;
this.setState({
buttonTouched: true
});
let trainer = {
firstName: firstName,
lastName: lastName,
email: email,
password: password
}
await this.props.registerTrainer(trainer);
if (!this.props.signUpHasError) {
this.setState({
displayModal: true
});
}
}
// render popup modal
_renderPopupModal() {
return (
<ModalPopup visible={this.state.displayModal}>
<TrainerMessage
onPress={() => this.navigateToMainFeed()}
/>
</ModalPopup>
);
}
// render
render() {
let { userRegistrationInProgress } = this.props;
return (
<View>
<ImageBackground source={BackgroundOnly} style={{ width: width, height: height }} >
<View style={{ marginTop: "5%" }}>
<ClickableIcon
source={BackArrow}
height={30}
width={30}
onIconPressed={() => {this.props.navigation.navigate("trainerExperience");}}
/>
</View>
<View style={styles.headerStyles}>
<HeadingText
fontSize={26}
fontWeight={300}
textAlign="left"
fontColor="#707070"
>
Personal Statement
</HeadingText>
</View>
<View>
{this._displayMessage()}
</View>
<View style={styles.detailInput}>
<DetailInput
inputStyle={styles.inputStyles}
height={120}
width={width - 40}
multiline={true}
numberOfLines={6}
underlineColorAndroid="transparent"
maxLength={500}
editable={!userRegistrationInProgress}
onChangeText={value => this.statementChangedHandler(value)}
/>
</View>
<View>
<RoundedButton
buttonStyle={styles.buttonStyle}
text="FINISH"
submitting={userRegistrationInProgress}
onPress={() => this.registerTrainer()}
disabled={!this._getFiledsNotEmptyStatus()}
/>
</View>
{this._renderPopupModal()}
</ImageBackground>
</View>
);
}
static navigationOptions = { header: null }
}

First close the modal and navigate the screen
this.setState({
displayModal: false
},()=>{
this.props.navigation.navigate("mainfeed");
});

Related

using classes and rendering api call in React Native

I am totally new in React Native, I am having problem rendering data from API call. When I do it inside function it is working for me when I am using useEffect... but in the Class I cannot use that.
Here is example of my code...
export default class Categories extends React.Component {
constructor(props) {
super(props);
this.state = {
loading: false,
data: [],
error: null,
};
}
componentDidMount() {
this.regionsGetRequest();
}
regionsGetRequest = () => {
this.setState({ loading: true });
const fetchData = async () => {
const result = await axios(
'https://...........json'
);
this.setState({
data: result.data,
error: result.error || null,
loading: false,
});
};
fetchData();
};
renderCategories = () => {
const categoryLive = this.state.data;
console.log(JSON.stringify(categoryLive));
I am getting in console: undefined, undefined... and then results as they should... like it is running 3 times for some reason... if I try to put above renderCategories:
componentDidMount() {
renderCategories();
}
I am getting just one undefined... when I connect variable categoryLive nothing is loading.
Sorry I have been strugling with this one... any help is really appreciated!!
No matter what I do, I am always getting 3 calls... first two empty object [], and third I get real results dumped in console. So my categories are not rendering.. they are empty.
Here is updated code, and I am posting whole file, it might ring some bells.
export default class Categories extends React.Component {
state = {
myData: [],
};
componentDidMount() {
axios
.get('https://..............json')
.then((res) => {
const myData = res.data;
this.setState({ myData });
});
}
renderCategories = () => {
const categoryLive = this.state.myData;
console.log(JSON.stringify(categoryLive));
const { navigation, route } = this.props;
const tabId = route.params?.tabId;
const categories = tabId
? categoryLive[tabId]
: categoryLive.victoria_bc;
//console.log(route.params?.tabId);
return (
<ScrollView
showsVerticalScrollIndicator={false}
contentContainerStyle={styles.categoryList}
>
<Block flex>
{categories.map((category) => (
<TouchableWithoutFeedback
key={`category-${category.id}`}
onPress={() => navigation.navigate('Category', { ...category })}
>
<Block flex card style={[styles.category, styles.shadow]}>
<ImageBackground
source={{ uri: category.image }}
style={[
styles.imageBlock,
{ width: width - theme.SIZES.BASE * 2, height: 252 },
]}
imageStyle={{
width: width - theme.SIZES.BASE * 2,
height: 252,
}}
>
<Block style={styles.categoryTitle}>
<Text size={18} bold color={theme.COLORS.WHITE}>
{category.title}
</Text>
</Block>
</ImageBackground>
</Block>
</TouchableWithoutFeedback>
))}
</Block>
</ScrollView>
);
};
render() {
return (
<Block flex center style={styles.categories}>
{this.renderCategories()}
</Block>
);
}
}
When I put it like this: I am getting default category ( and all data just fine... ) but my navigation is not working any more... (route.params?.tabId is not updating)
axios
.get('https://.............json')
.then((res) => {
this.setState({
myData: res.data,
error: res.error || null,
loading: false,
});
console.log('inside .then----' + JSON.stringify(this.state.myData));
const { navigation, route } = this.props;
const tabId = route.params?.tabId;
const tmpCategories = tabId
? this.state.myData[tabId]
: this.state.myData.victoria_bc;
this.setState({ categories: tmpCategories });
//console.log(route.params?.tabId);
});
If I put it like this as below... category is empty for me:
axios
.get('https://.............json')
.then((res) => {
this.setState({
myData: res.data,
error: res.error || null,
loading: false,
});
console.log('inside .then----' + JSON.stringify(this.state.myData));
});
const { navigation, route } = this.props;
const tabId = route.params?.tabId;
const tmpCategories = tabId
? this.state.myData[tabId]
: this.state.myData.victoria_bc;
this.setState({ categories: tmpCategories });
//console.log(route.params?.tabId);
Final code that is working for me..
export default class Categories extends React.Component {
constructor(props) {
super(props);
this.state = {
loading: true,
myData: [],
error: null,
};
}
componentDidMount() {
this.renderCategories();
}
renderCategories = () => {
axios
.get('https://.............json')
.then((res) => {
this.setState({
myData: res.data,
error: res.error || null,
loading: false,
});
//console.log('inside .then----' + JSON.stringify(this.state.myData));
});
};
render() {
if (this.state.loading) {
return (
<View
style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}
>
<ActivityIndicator />
</View>
);
} else {
const { navigation, route } = this.props;
const tabId = route.params?.tabId;
const categories = tabId
? this.state.myData[tabId]
: this.state.myData.victoria_bc;
//console.log(route.params?.tabId);
return (
<Block flex center style={styles.categories}>
<ScrollView
showsVerticalScrollIndicator={false}
contentContainerStyle={styles.categoryList}
>
<Block flex>
{categories.map((category) => (
<TouchableWithoutFeedback
key={`category-${category.id}`}
onPress={() =>
navigation.navigate('Category', { ...category })
}
>
<Block flex card style={[styles.category, styles.shadow]}>
<ImageBackground
source={{ uri: category.image }}
style={[
styles.imageBlock,
{ width: width - theme.SIZES.BASE * 2, height: 252 },
]}
imageStyle={{
width: width - theme.SIZES.BASE * 2,
height: 252,
}}
>
<Block style={styles.categoryTitle}>
<Text size={18} bold color={theme.COLORS.WHITE}>
{category.title}
</Text>
</Block>
</ImageBackground>
</Block>
</TouchableWithoutFeedback>
))}
</Block>
</ScrollView>
</Block>
);
}
}
}
export default class Categories extends React.Component {
constructor(props) {
super(props);
this.state = {
loading: false,
myData: [],
error: null,
categories: []
};
}
componentDidMount() {
renderCategories();
}
renderCategories = () => {
this.setState({ loading: true });
axios
.get('https://..............json')
.then((res) => {
this.setState({ myData: res.data,
error: res.error || null,
loading: false
});
const categoryLive = this.state.myData;
console.log(JSON.stringify(categoryLive));
});
};
render() {
// Set params in your render method :
const { navigation, route } = this.props;
const tabId = route.params?.tabId;
if (this.state.loading){
return (
<View style={{ flex : 1, alignItems: 'center', justifyContent: 'center' }}>
<ActivityIndicator/>
</View>
);
}
return (
// assign in your return statement
this.setState({ categories: tabId
? categoryLive[tabId]
: categoryLive.victoria_bc;})
//console.log(route.params?.tabId);
const { categories } = this.state.categories;
<Block flex center style={styles.categories}>
<ScrollView
showsVerticalScrollIndicator={false}
contentContainerStyle={styles.categoryList}
>
<Block flex>
{categories.map((category) => (
<TouchableWithoutFeedback
key={`category-${category.id}`}
onPress={() => navigation.navigate('Category', { ...category })}
>
<Block flex card style={[styles.category, styles.shadow]}>
<ImageBackground
source={{ uri: category.image }}
style={[
styles.imageBlock,
{ width: width - theme.SIZES.BASE * 2, height: 252 },
]}
imageStyle={{
width: width - theme.SIZES.BASE * 2,
height: 252,
}}
>
<Block style={styles.categoryTitle}>
<Text size={18} bold color={theme.COLORS.WHITE}>
{category.title}
</Text>
</Block>
</ImageBackground>
</Block>
</TouchableWithoutFeedback>
))}
</Block>
</ScrollView>
</Block>
);
}
}

How to null check and navigate to new screen on click submit when textinput and submit button both are in different js files in react native?

render(){
return (
<ImageBackground
source={require('../images/back02.png')}
style={styles.bgscreen}
>
<KeyboardAvoidingView behavior='position'>
<Image
style={styles.headImage}
source={require('../images/login_img.png')}
/>
<ImgBack/>
</KeyboardAvoidingView>
<BottomButton navigation={this.props.navigation} />
</ImageBackground>
);}
}
ImgBack contains username and password textinput.
BottomButton contains the submit button
I want to navigate to new activity when submit button clicked. navigation to new screen is working perfectly but before navigating i want to null check the TextInput which are on
I am new to React-Native. Complete Beginner here. I want even know what to do. Help.
ImgBack.js file
class imgBack extends React.Component {
constructor()
{
super();
this.state = { hidePassword: true }
}
managePasswordVisibility = () =>
{
this.setState({ hidePassword: !this.state.hidePassword });
}
usernameValidate = (EnteredValue) =>{
var TextLength = EnteredValue.length.toString();
if(TextLength == 10 ){
Alert.alert("Sorry, You have reached the maximum input limit.")
}
else if(TextLength == 0){
Alert.alert("Username can't be blank")
}
}
passValidate = (EnteredValue) =>{
var TextLength = EnteredValue.length.toString();
if(TextLength == 10 ){
Alert.alert("Sorry, You have reached the maximum input limit.")
}
else if(TextLength == 0){
Alert.alert("Username can't be blank")
}
}
render(){
return (
<ImageBackground resizeMode='contain'
source={require('../images/login_back.png')}
style={{
marginHorizontal: 10,
height: 290,
padding: 30,
}}>
<View style={
styles.textInputContainer
} >
<TextInput
placeholder="Username"
underlineColorAndroid = "transparent"
placeholderTextColor="#000000"
maxLength={10}
onChangeText={ EnteredValue => this.usernameValidate(EnteredValue) }
/>
</View>
<View style = { styles.textInputContainer }>
<TextInput
onChangeText={ EnteredValue => this.passValidate(EnteredValue) }
underlineColorAndroid = "transparent"
secureTextEntry = { this.state.hidePassword }
placeholder="Password"
placeholderTextColor="#000"
/>
<TouchableOpacity style = { styles.visibilityBtn } onPress = { this.managePasswordVisibility }>
<Image source = { ( this.state.hidePassword ) ? require('../images/eye_close_icon.imageset/eye_close_icon.png') : require('../images/eye_icon.imageset/eye_icon.png') } style = { styles.btnImage } />
</TouchableOpacity>
</View>
</ImageBackground>
)
}
} ```
**Bottombutton File**
class bottomButon extends Component {
render(){
return (
<ImageBackground
style={{ height: 80, marginLeft: '20%', marginTop: 10 }}
resizeMode={'center'}
source={require('../images/btn_back.png')} >
<TouchableOpacity
onPress={ this.login } >
<Text style={{ textAlign: 'center', marginTop: 25 }}>Submit & SYNC</Text>
</TouchableOpacity>
</ImageBackground>
)
} }
export default bottomButon; ```
solution:
constructor(props) {
super(props);
this.state = {
hidePassword: true,
username: '',
password: '',
};
}
validUserPass = async () => {
try {
if (this.state.username === '') {
Alert.alert('Username is required !');
} else if (this.state.password === '') {
Alert.alert('Password is required !');
} else {
this.props.navigation.navigate('selectEmoji');
}
} catch (error) {
console.warn(error);
}
};
it helped me solve my issue.

How to refresh/re-render flatlist on react-native?

im trying to refresh my flatlist from some page without going back to the principal menu, but it doesnt work.
I've already readed about extraData, but it doesnt work either.
Basiclly my program is like that:
I have a page called "passwords" and i add some passwords there from another page called "add passwords". When i click to add a password, i want to refresh the flatlist from the page "passwords" to show me the password that i just added.
This is my code from the page "add passwords"
...
state = {
arr: [],
local: '',
password: '',
obj: {
local: '',
password: ''
},
count: 1,
texto: ''
};
componentDidMount() {
//Here is the Trick
const { navigation } = this.props;
//Adding an event listner om focus
//So whenever the screen will have focus it will set the state to zero
this.focusListener = navigation.addListener('didFocus', () => {
this.setState({ count: 0 });
});
}
storeItem(item) {
try {
//we want to wait for the Promise returned by AsyncStorage.setItem()
//to be resolved to the actual value before returning the value~
console.log(item)
var joined = this.state.arr.concat(item);
console.log(joined)
this.setState({ arr: joined })
AsyncStorage.setItem('array', JSON.stringify(joined));
console.log(this.state.arr)
} catch (error) {
console.log(error.message);
}
}
componentWillMount() {
AsyncStorage.getItem('array').then(array => {
item = JSON.parse(array)
array ? this.setState({ arr: item }) : null;
console.log(item)
})
}
render() {
return (
<View style={styles.container}>
<TextInput
style={{ height: 40, borderColor: 'gray', borderWidth: 1 }}
onChangeText={(text) => this.setState({ local: text })}
value={this.state.local}
/>
<TextInput
secureTextEntry={true}
style={{ height: 40, borderColor: 'gray', borderWidth: 1 }}
onChangeText={(text) => this.setState({ password: text })}
value={this.state.password}
/>
<Button title='Adicionar'
onPress={() => this.storeItem({ local: this.state.local, password: this.state.password }) + alert("Adicionado com sucesso!") + this.props.navigation.navigate('Passwords')}
></Button>
</View>
);
}
}
And this is my page "passwords" where i want to refresh
componentWillMount() {
const { navigation } = this.props;
this.willFocusListener = navigation.addListener(
'willFocus',
() => {
this.setState({ count: 10 })
}
)
AsyncStorage.getItem('array').then(array => {
item = JSON.parse(array)
item ? this.setState({ arr: item }) : null;
console.log(this.state.arr)
})
}
renderItem = ({ item }) => (
<View style={{ flexDirection: 'row' }} style={styles.passwordContainer}>
<Text> {item.local} </Text>
<Text> {item.password} </Text>
</View>
)
render() {
return (
<View style={styles.container}>
<FlatList
data={this.state.arr}
renderItem={this.renderItem}
extraData={this.state} //this is what i tryied
/>
</View>
);
You can use your listener to update the state.
componentWillMount() {
this.willFocusListener = navigation.addListener(
'willFocus',
() => this.updateData()
}
updateData = () => {
this.setState({ count: 10 });
AsyncStorage.getItem('array').then(array => {
item = JSON.parse(array)
item ? this.setState({ arr: item }) : null;
console.log(this.state.arr)
});
}
Any state changes will rerender items.

React Native Pass Index to Props

I have a modal that contain icons and description and status, and i want to pass the icons and descriptions from index to the modal,I already pass the status. is there anyway to do that? sorry i'm still new to react native and thanks in advance
this is my index.js
export const img =
{
itemStatus: {
"Open": { name: 'open-book', type: 'entypo', color: '#ffb732', desc:'New Attribut, New Attention'},
"Approved": { name: 'checklist', type: 'octicon', color: '#3CB371', desc:'Approved by SPV/MNG' },
"Escalated": { name: 'mail-forward', type: 'font-awesome', color: '#ffb732', desc:'Escalated to SPV/MNG' },
"Deliver Partial": { name: 'arrange-send-to-back', type: 'material-community', color: '#8B4513', desc:'Some items in a DO have not arrived/was faulty' },
};
and this is my container
class MyRequest extends React.Component {
constructor() {
super();
this.state = {
currentStatus: null,
refreshing: false,
fetchStatus: null
};
handleShowModal = (status) =>{
this.setState({
currentStatus: status,
});
}
handleDismissModal = () =>{
this.setState({currentStatus: null});
}
<View style={[styles.panelContainer, status === 'success' ? {} : { backgroundColor: color.white }]}>
<FlatList
showsVerticalScrollIndicator={false}
progressViewOffset={-10}
refreshing={this.state.refreshing}
onRefresh={this.onRefresh.bind(this)}
onMomentumScrollEnd={(event) => event.nativeEvent.contentOffset.y === 0 ? this.onRefresh() : null}
data={content}
renderItem={({ item }) => item}
keyExtractor={(item, key) => key.toString()}
/>
</View>
<IconModal visible={this.state.modalVisible} close={this.handleDismissModal} icon={} status={this.state.currentStatus} desc={} />
}
and this is my modal
const IconModal = (props) => {
return(
<Modal
isVisible={props.visible}
onBackdropPress={props.close}
>
<View style={styles.dialogBox}>
<View style={styles.icon}>
<Icon>{props.icon}</Icon>
</View>
<View style={styles.text}>
<Text style={styles.status}>{props.status}</Text>
<Text>{props.desc}</Text>
</View>
<TouchableOpacity onPress={props.close}>
<View>
<Text style={styles.buttonText}>GOT IT</Text>
</View>
</TouchableOpacity>
</View>
</Modal>
)
}
It's a bit unclear how you plan on mapping against img.itemStatus index but you can just reference the object you want as such.
import img from '....path_to_index.js'
...
// const currentItemStatus = img.itemStatus.Open
// OR
const itemStatus = 'Open' // Or 'Approved', 'Escalated', 'Deliver Partial'
const currentItemStatus = img.itemStatus[itemStatus]
...
<IconModal
visible={this.state.modalVisible}
close={this.handleDismissModal}
icon={currentItemStatus.name} // Passing name
status={this.state.currentStatus}
desc={currentItemStatus.desc} // Passing desc
/>
...
Hope this was helpful

How to pass data from screen to screen from flat list item

How do i able to pass the list items from first screen to the third screen, i am able to pass data on to the second screen but not the third screen. What i'm trying to achieve is how do i able to edit the list item on the third screen and inside the edit text input get the data and update. By the way, i'm using flat list item, because list view is deprecated. Below are my codes and screenshots.
First Screenshot
Second screenshot
Third screenshot
First screenshot coding
class SecondScreen extends Component {
constructor(props){
super(props);
this.state = {
loading: true,
email: '',
name: '',
title: '',
description: '',
error: '',
dataSource: [],
isFetching: false
}
}
onPress(item){
this.props.navigation.navigate(
'DetailsScreen',
{item},
);
}
renderItem = ({ item }) => {
return (
<TouchableOpacity style={{ flex: 1, flexDirection: 'row',
marginBottom: 3}}
onPress={() => { this.onPress(item) }}>
<View style={{ flex: 1, justifyContent: 'center', marginLeft:
5}}>
<Text style={{ fontSize: 18, color: 'green', marginBottom:
15}}>
{"ID - "+item.id}
</Text>
<Text style={{ fontSize: 18, color: 'green', marginBottom:
15}}>
{"Title - "+item.title}
</Text>
<Text style={{ fontSize: 16, color: 'red'}}>
{"Description - "+item.description}
</Text>
</View>
</TouchableOpacity>
)
}
renderSeparator = () => {
return (
<View
style={{height: 1, width: '100%', backgroundColor: 'black'}}>
</View>
)
}
ListEmptyView = () => {
return (
<View style={styles.container}>
<Text style={{textAlign: 'center'}}> No job available.</Text>
</View>
);
}
handleBackButton = () => {
Alert.alert(
'Exit App',
'Exiting the application?', [{
text: 'Cancel',
onPress: () => console.log('Cancel Pressed'),
style: 'cancel'
}, {
text: 'OK',
onPress: () => BackHandler.exitApp()
},],{
cancelable: false
}
)
return true;
}
componentDidMount(){
this.getAvailableJob()
BackHandler.addEventListener('hardwareBackPress',
this.handleBackButton);
}
getAvailableJob() {
const headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + this.props.token
};
axios({
method: 'GET',
url: 'http://192.168.1.201:8000/api/jobs',
headers: headers,
}).then((response) => {
console.log('response3',response)
console.log('response4',this.props.token)
this.setState({
dataSource: response.data,
isFetching: false
});
}).catch((error) => {
console.log(error);
this.setState({
error: 'Error retrieving data',
loading: false
});
});
}
componentWillUnmount() {
BackHandler.removeEventListener('hardwareBackPress',
this.handleBackButton);
}
onRefresh() {
this.setState({ isFetching: true }, function() { this.getAvailableJob()
});
}
render() {
const { container, emailText, errorText } = styles;
const { loading, email, name, error, title, description } = this.state;
return(
<View style={container}>
<FlatList
data={this.state.dataSource}
onRefresh={() => this.onRefresh()}
refreshing={this.state.isFetching}
renderItem={this.renderItem}
keyExtractor={(item, index) => index.toString()}
ListEmptyComponent={this.ListEmptyView}
ItemSeparatorComponent={this.renderSeparator}
/>
</View>
);
}
}
export default withNavigation(SecondScreen);
Second screenshot coding
class DetailsScreen extends React.Component {
handleBackButton = () => {
this.props.navigation.popToTop();
return true;
}
componentDidMount(){
BackHandler.addEventListener('hardwareBackPress',
this.handleBackButton);
}
componentWillUnmount() {
BackHandler.removeEventListener('hardwareBackPress',
this.handleBackButton);
}
onPress(item){
this.props.navigation.push(
'EditDetailsScreen',
{item},
);
}
render() {
const { backButton } = styles;
let item = this.props.navigation.state.params.item;
return (
<View style={styles.container}>
<View style={[styles.container2, { backgroundColor: 'yellow' },
styles.hiddenContainer]}>
<Text style = { styles.TextStyle }> ID {
this.props.navigation.state.params.item.id }</Text>
</View>
<Text style = { styles.TextStyle }> Title {
this.props.navigation.state.params.item.title }</Text>
<Text style = { styles.TextStyle }> Description {
this.props.navigation.state.params.item.description }</Text>
<TouchableOpacity
style = {styles.submitButton}
onPress = {() => { this.onPress(item) }}>
<Text style = {styles.submitButtonText}> Edit </Text>
</TouchableOpacity>
</View>
);
}
}
export default withNavigation(DetailsScreen);
Third screenshot coding
class EditDetailsScreen extends React.Component {
handleTitle = (text) => {
this.setState({ title: text })
}
handleDescription = (text) => {
this.setState({ description: text })
}
handleBackButton = () => {
this.props.navigation.popToTop();
return true;
}
componentDidMount(){
BackHandler.addEventListener('hardwareBackPress',
this.handleBackButton);
}
componentWillUnmount() {
BackHandler.removeEventListener('hardwareBackPress',
this.handleBackButton);
}
updateJobDetails = () => {
const headers = {
'Accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Bearer ' + this.props.token
};
axios({
method: 'PUT',
url: 'http://192.168.1.201:8000/api/jobs',
headers: headers,
}).then((response) => {
this.setState({
title: response.data,
description: response.data,
loading: false
});
}).catch((error) => {
console.log(error);
this.setState({
error: 'Error retrieving data',
loading: false
});
});
}
render() {
return (
<View style={styles.container}>
<View style={[styles.container2, { backgroundColor: 'yellow' },
styles.hiddenContainer]}>
<Text style = { styles.TextStyle }> ID {
this.props.navigation.state.params.item.id }</Text>
</View>
<Text style = { styles.TextStyle }> Title {
this.props.navigation.state.params.item.title }</Text>
<Text style = { styles.TextStyle }> Description {
this.props.navigation.state.params.item.description }</Text>
<TextInput style = {styles.input}
underlineColorAndroid = "transparent"
placeholder = "Edit Title"
placeholderTextColor = "#9a73ef"
autoCapitalize = "none"
onChangeText = {this.handleTitle}/>
<TextInput style = {styles.input}
underlineColorAndroid = "transparent"
placeholder = "Edit Description"
placeholderTextColor = "#9a73ef"
autoCapitalize = "none"
onChangeText = {this.handleDescription}/>
<TouchableOpacity
style = {styles.submitButton}
onPress = {this.updateJobDetails}>
<Text style = {styles.submitButtonText}> Submit </Text>
</TouchableOpacity>
</View>
);
}
}
export default withNavigation(EditDetailsScreen);
I can update using postman but not in react native, and also in postman i had to set the Body to use x-www-form-urlencoded instead of form-data. So how do i able to update in react native? Any help would be much appreciated. Below is my postman screenshot.
Postman
A suggestion is to use a state container like react-redux, but if you don't want: you can pass a function in the props like
<renderedItem update={(newVal) => this.setState({ val: newVal})}>
and then in the renderedItem you can call this function with new value like so:
this.props.update(this.state.newVal)
I've solved the problem by using qs.stringify(data). Below is my updated code.
updateJobDetails = () => {
url = 'http://192.168.1.201:8000/api/jobs/' + this.props.navigation.state.params.item.id;
const qs = require('qs');
const data = {title:this.state.TextInput_Title,
description:this.state.TextInput_Description};
const options = {
method: 'PUT',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Bearer ' + this.props.token
},
data: qs.stringify(data),
url
}
axios(options).then((response) => {
console.log('update response',response)
Alert.alert(
'Update successful',
'Your details has been updated', [{
text: 'OK',
onPress: () => this.props.navigation.popToTop()
},]
,{
cancelable: false
}
)
this.setState({
loading: false,
});
}).catch((error) => {
Alert.alert("Please Enter All the Values.");
console.log(error);
this.setState({
error: 'Error retrieving data',
loading: false
});
});
}
render() {
return (
<View style={styles.container}>
<View style={[styles.container2, { backgroundColor: 'yellow' },
styles.hiddenContainer]}>
<Text style = { styles.TextStyle }> ID {
this.props.navigation.state.params.item.id }</Text>
</View>
<Text style = {styles.TextStyle2}>
Title:
</Text>
<TextInput style = {styles.input}
underlineColorAndroid = "transparent"
placeholder = "Edit Title"
placeholderTextColor = "#9a73ef"
autoCapitalize = "none"
value={this.state.TextInput_Title}
onChangeText = { TextInputValue => this.setState({TextInput_Title: TextInputValue})}/>
<Text style = {styles.TextStyle2}>
Description:
</Text>
<TextInput style = {styles.input}
underlineColorAndroid = "transparent"
placeholder = "Edit Description"
placeholderTextColor = "#9a73ef"
autoCapitalize = "none"
value={this.state.TextInput_Description}
onChangeText = { TextInputValue =>
this.setState({TextInput_Description: TextInputValue})}/>
<TouchableOpacity
style = {styles.submitButton}
onPress = {this.updateJobDetails}>
<Text style = {styles.submitButtonText}> Submit </Text>
</TouchableOpacity>
</View>
);
}