JSON.stringify cannot serialize cyclic structure when passing state - reactjs

I have problem when fetching data in react-native. I'm trying to send parts of my state in body of POST. I dont understand where is cyclic structure in my code. I dont see any cyclic structures.
I know the error is caused by state because when i simply put some strings in body everything is going alright.
import React from 'react';
import {Text, View, Button, StyleSheet, TextInput, TouchableOpacity} from "react-native";
export default class AddKidScreen extends React.Component {
constructor(props) {
super(props);
this.state = {
name: '',
age: '',
parentID: props.navigation.getParam('myID', 0)
}
}
handleAddKid() {
let url = "https://piotr2.scementowani.pl/apiPiotr";
let name = this.state.name;
let age = this.state.age;
fetch(url, {
method: 'POST',
headers: {
'Content-Type': "application/json",
},
body: JSON.stringify({
method: "addKid",
name: name,
age: age,
}),
})
.then(response => response.json())
.then(responseJson => {
this.props.navigation.navigate('Main');
})
.catch((error) => {
console.error(error);
});
}
updateValue(text,field) {
if (field == 'name') {
this.setState({
name: text,
})
} else if (field == 'age' ){
this.setState( {
age: text,
})
}
}
render() {
return(
<View>
<View style={{flexDirection: 'row', width: '100%'}}>
<Text>
Imię:
</Text>
<TextInput
placeholder = "Imię"
onChange = {(text) => this.updateValue(text,'name')}
/>
</View>
<View style={{flexDirection: 'row', width: '100%'}}>
<Text>
Wiek:
</Text>
<TextInput
placeholder = "Wiek"
onChange = {(text) => this.updateValue(text,'age')}
/>
</View>
<TouchableOpacity onPress={this.handleAddKid.bind(this)}>
<Text>DODAJ</Text>
</TouchableOpacity>
</View>
)
}
}
When running handleAddKid()
I get JSON.stringify cannot serialize cyclic structure.

Related

React Native Mathematical operation not working properly

I am diving to this question from my previous question here: React Native mathematical actions not working
However, I got the problem from the answer there and updated my code (I know that I did not solve the illegal state modifying, the main system is not working properly).
App.js
import React, { Component } from 'react';
import {
ActivityIndicator,
Text,
View,
StyleSheet,
FlatList,
Alert,
TouchableOpacity,
ScrollView,
TextInput
} from 'react-native';
import {
Avatar,
Card,
Button,
Divider,
ListItem,
Image
} from 'react-native-elements';
import Icon from 'react-native-vector-icons/FontAwesome';
import HTML from 'react-native-render-html';
import UserAvatar from 'react-native-user-avatar';
import { StackNavigator } from 'react-navigation';
import { createAppContainer } from 'react-navigation';
import { createStackNavigator } from 'react-navigation-stack';
import Cookies from 'universal-cookie';
import Heart from './components/heart';
const cookies = new Cookies();
class HomeScreen extends React.Component {
static navigationOptions = {
title: '',
};
constructor(props) {
super(props);
this.state = {
Loading: true,
data: [],
imageUrls: [],
isPress: false,
loveAction: '',
};
}
fetchLeash(user) {
return fetch('https://lishup.com/app/', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({ user }),
})
.then((response) => response.json())
.then((responseJson) => {
this.setState({ data: responseJson });
Promise.all(
responseJson.map(({ images }) => this.fetchImage(images))
).then((imageUrls) => this.setState({ imageUrls }));
})
.catch((error) => {
Alert.alert('error!');
})
.finally(() => {
this.setState({ Loading: false });
});
}
fetchImage(image) {
return fetch('https://lishup.com/app/fetch-image.php', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({ image }),
})
.then((response) => response.json())
.then((responseJson) =>
// Filter elements with empty string URLs, then app just the URL
responseJson.filter(({ url }) => url).map(({ url }) => url)
);
}
componentDidMount() {
this.fetchLeash(cookies.get('user'));
}
heartOnPress = (id, writer) => {
this.setState((state) => {
const data = state.data.map((el) => {
if(el.id === id) {
if(el.isLiked == true){
el.loves = el.loves - 1;
} else {
el.loves = el.loves + 1;
}
el.isliked = !el.isliked;
}
return el;
});
const isPress = !state.isPress
return { data, isPress };
});
fetch('https://lishup.com/app/love.php', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
id: id,
user: cookies.get('user'),
author: writer
}),
})
.then((response) => response.json())
.then((responseJson) => {
});
};
renderLeash = ({ item, index }) => (
<View>
<Card
style={{
height: 100,
justifyContent: 'center',
alignItems: 'center',
}}>
<ListItem
leftAvatar={{
title: item.user,
source: { uri: item.userpic },
}}
title={item.user}
subtitle={item.time}
chevron
/>
<Divider style={{ margin: 5, backgroundColor: 'white' }} />
<HTML html={item.text} />
<ScrollView
horizontal={true}
>
<View style={{flex:1, flexDirection:'row'}}>
{this.state.imageUrls[index] && this.state.imageUrls[index].length
? this.state.imageUrls[index].map((uri) => (
<Image
source={{ uri }}
style={{ flex:1, width: 500, height: 500, resizeMode: 'contain'}}
PlaceholderContent={<ActivityIndicator />}
/>
))
: null}
</View>
</ScrollView>
<Text>{item.loves}</Text>
<Text>{this.state.loveAction}</Text>
<Heart isLiked={item.isliked} main={item.user} id={item.id} onPress={this.heartOnPress} />
</Card>
</View>
);
render() {
if (this.state.Loading == true) {
cookies.set('user', 'LishUp', { path: '/' });
return (
<ActivityIndicator
size="large"
style={{ marginTop: 100 }}
color="#0000ff"
/>
);
} else {
return (
<View>
<FlatList
style={{ width: 400 }}
data={this.state.data}
keyExtractor={(item, idx) => idx}
renderItem={this.renderLeash}
/>
</View>
);
}
}
}
const styles = StyleSheet.create({});
const RootStack = createStackNavigator(
{
Home: { screen: HomeScreen },
},
{
initialRouteName: 'Home',
}
);
export default createAppContainer(RootStack);
heart.js
import React from 'react';
import { View, TouchableOpacity } from 'react-native';
import Icon from 'react-native-vector-icons/FontAwesome';
const Heart = ({ isLiked, onPress, main, id }) => {
return (
<View>
{isLiked ? (
<TouchableOpacity onPress={() => onPress(id, main)}>
<Icon name="heart" size={30} color="red" />
</TouchableOpacity>
) : (
<TouchableOpacity onPress={() => onPress(id, main)}>
<Icon name="heart" size={30} color="grey" />
</TouchableOpacity>
)}
</View>
);
};
export default Heart;
The problem right is: Suppose, there is 2 loves in a post. I pressed love. It just adds 1 beside the number 2 instead of doing an addition. Like- it becomes 21 instead of being 3
I can't understand where is the mistake, does react native avoid this kind of mathematical operation?
My snack: https://snack.expo.io/#nothingtosay/privileged-toffee
First of call you can change you Heart component
import React from 'react';
import { View, TouchableOpacity } from 'react-native';
import Icon from 'react-native-vector-icons/FontAwesome';
const Heart = ({ isLiked, onPress, main, id }) => {
return (
<View>
<TouchableOpacity onPress={() => onPress(id, main)}>
<Icon name="heart" size={30} color={isLiked?"red":"grey"} />
</TouchableOpacity>
</View>
);
};
export default Heart;
and you can parse the el.loves value before adding and subtracting Like this
el.loves = parseInt(el.loves) - 1;
el.loves = parseInt(el.loves) + 1;
It is just treating your “loves” as a string. Convert to number first with parseInt:
if(el.isLiked == true){
el.loves = parseInt(el.loves) - 1;
} else {
el.loves = parseInt(el.loves) + 1;
}

Understanding React Natives setState and componentWillMount from FlatList

So I'm trying to make a simple application with expo and expo audio that will generate a list of audio buttons and text. But I cannot figure out how react works regarding redrawing the setState OUTSIDE componentWillMount and how to remake a soundobject with a new URI
So right now it will work but only playing the FIRST uri, I assume this is because the object still exists.
And it will not change the state of the button, I know this is because react cant see its changing for some reason from FlatList
It works outside of it, if I only make one button in renders view.
FlatList will render the setStates if I use LegacyImplementation=true .. But Im warned this is deprecated. And it renders it for all buttons at the same time
This is my handlerClass:
export class TSSGetter extends React.Component {
constructor(props){
super(props);
this.state ={
isLoading: true,
playingStatus: "Play"
}
}
retrieveData() {
const endpoint = 'http://127.0.0.1:3333/get'
const data = {
"userId": "123412341234",
"hmac": "detteerikkeenrigtighmac"
}
return new Promise((resolve, reject) => {
fetch(endpoint, {
method: 'POST',
headers: {
'Accept': 'application/json',
'content-type':'application/json'
},
body: JSON.stringify(data)
})
.then((resp) => {
console.log('hej return')
return resp.json();
})
.then((resp) => {
resolve(resp);
console.log('resp')
}).catch(function(error) {
console.log(error,'naeh')
});
});
}
componentDidMount(){
this.retrieveData()
.then((resp) => {
var pages = resp.books.contentObjects
pages.map((userData) => {
console.log('superduper pages', userData.contentObjectId)
})
this.setState({
isLoading: false,
dataSource: resp.books.contentObjects,
dataroot: resp.books
});
}).catch((err) => {
//handle error
console.log("Api call error2");
alert(err);
})
}
async _playRecording(AudioURL) {
console.log(AudioURL)
const { sound } = await Audio.Sound.createAsync(
{uri: AudioURL},
{
shouldPlay: true,
isLooping: true,
},
this._updateScreenForSoundStatus,
);
this.sound = sound;
this.setState({
playingStatus: 'playing'
});
}
_updateScreenForSoundStatus = (status) => {
if (status.isPlaying && this.state.playingStatus !== "playing") {
this.setState({ playingStatus: "playing" });
} else if (!status.isPlaying && this.state.playingStatus === "playing") {
this.setState({ playingStatus: "donepause" });
}
};
async _pauseAndPlayRecording() {
if (this.sound != null) {
if (this.state.playingStatus == 'playing') {
console.log('pausing...');
await this.sound.pauseAsync();
console.log('paused!');
this.setState({
playingStatus: 'donepause',
});
} else {
console.log('playing...');
await this.sound.playAsync();
console.log('playing!');
this.setState({
playingStatus: 'playing',
});
}
}
}
_syncPauseAndPlayRecording() {
if (this.sound != null) {
if (this.state.playingStatus == 'playing') {
this.sound.pauseAsync();
} else {
this.sound.playAsync();
}
}
}
_playAndPause = (AudioURL) => {
console.log(AudioURL)
switch (this.state.playingStatus) {
case 'Play':
this._playRecording(AudioURL);
break;
case 'donepause':
case 'playing':
this._pauseAndPlayRecording();
break;
}
}
render(){
if(this.state.isLoading){
return(
<View style={{flex: 1, padding: 20}}>
<ActivityIndicator/>
</View>
)
}
const styling = {
flex: 1,
paddingTop:10
// flexDirection: 'row'
}
const data = this.state.dataroot;
return(
<View style={styles.container}>
<FlatList
data={this.state.dataSource}
renderItem={({item}) =>
<View>
<TouchableOpacity style={styles.button} onPress={() => this._playAndPause(item.AudioURL)}>
<Text style={styles.buttonText}>
{this.state.playingStatus}+ {item.contentObjectId}
</Text>
</TouchableOpacity>
<Text style={styles.description}>
{item.text},
</Text>
</View>
}
keyExtractor={(item, index) => item.contentObjectId}
/>
</View>
);
}
}
UPDATE: setting extraData={this.state} in flatlist updates the button.. But all the buttons. How do I change the scope of the button?
You could create a specific component for the items in the FlatList. Each of the items will then have their own state.
import React, { Component } from "react";
import { StyleSheet, Text, View } from "react-native";
import { FlatList } from "react-native-gesture-handler";
export default class App extends React.Component {
render() {
return (
<View style={styles.container}>
<FlatList
keyExtractor={(item, index) => index.toString()}
data={[1, 2, 3, 4, 5]}
renderItem={({ item }) => <Sound />}
/>
</View>
);
}
}
class Sound extends Component {
constructor() {
super();
this.state = {
status: "IDLE"
};
}
onChangeState = value => {
this.setState({
status: value
});
};
render() {
const { status } = this.state;
return (
<View style={{width: 200,paddingVertical: 10}}>
<Text>Status: {status}</Text>
<View style={{ flex: 1,flexDirection: "row", justifyContent: "space-between" }}>
<Text onPress={() => this.onChangeState("PLAYING")}>PLAY</Text>
<Text onPress={() => this.onChangeState("STOPPED")}>STOP</Text>
<Text onPress={() => this.onChangeState("PAUSED")}>PAUSE</Text>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: 100,
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center"
}
});
I checked out in the docs, here, and I saw that it will re-render just if you pass the state prop, see this explanations:
By passing extraData={this.state} to FlatList we make sure FlatList itself will re-render when the state.selected changes. Without setting this prop, FlatList would not know it needs to re-render any items because it is also a PureComponent and the prop comparison will not show any changes.

Navigation from one page to another in react native using navigate

I am currently learning react native. I want to navigate from one screen to another using navigate() function. Navigate function is placed inside a fetch() function, so after i get the response from the server, I should be redirected to the next page. But currently i an having problem as the navigation code is not working if i put inside the fetch(). If i remove the code and place it outside the fetch then it is working.
Below is my written code (StepOne):
import React, { Component } from 'react';
import { Text, View, StyleSheet, ImageBackground, TextInput, TouchableOpacity, Alert } from 'react-native';
import { Tile } from 'react-native-elements';
export default class StepOne extends Component {
static navigationOptions = {
header: null
};
constructor(props) {
super(props);
this.state = {
userEmail : '',
userPhone : ''
}
}
moveToStepTwo = () => {
const {userEmail} = this.state;
const {userPhone} = this.state;
if(userEmail == '' || userPhone == '') {
Alert.alert('Warning' , 'Please Insert All the Required Details !!!!');
} else {
let url = 'registerProcessGetEmailValidity.jsp?';
let param_one = 'user_email='+userEmail;
let seperator_param = '&';
let full_url = '';
full_url = url + param_one;
let header = {
'Accept': 'application/json',
'Content-Type': 'application/json'
};
fetch( full_url, {
method: 'GET',
headers: header,
})
.then(function(response) {
return response.json();
})
.then(function(myJson) {
console.log(myJson);
if(myJson.message == 'No User') {
this.props.navigation.navigate('StepTwo', { userEmail: this.state.userEmail , userPhone: this.state.userPhone } );
} else if (myJson.message == 'Got User') {
Alert.alert('Warning' , 'Email is registered, Choose different email !!!!');
}
});
}
}
render() {
const { navigate } = this.props.navigation;
return (
<View style={styles.container}>
<ImageBackground source={require('../../img/background1.jpg')} style={styles.backgroundImage}>
<View style={styles.content}>
<Text style={styles.logo}> -- STEP 1 -- </Text>
<View style={styles.inputContainer}>
<TextInput
underlineColorAndroid='transparent' style={styles.input} placeholder='ENTER EMAIL'
onChangeText = {userEmail => this.setState({userEmail})} >
</TextInput>
<TextInput
underlineColorAndroid='transparent' keyboardType = {'numeric'} maxLength={12}
style={styles.input} placeholder='ENTER PHONE NUMBER' onChangeText = {userPhone => this.setState({userPhone})} >
</TextInput>
</View>
<View style={styles.buttonHolder}>
<TouchableOpacity style={styles.buttonContainer} onPress={ this.moveToStepTwo }>
<Text style={styles.buttonText}>NEXT</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.buttonContainer} onPress={ ()=> navigate('Home') } >
<Text style={styles.buttonText}>CANCEL</Text>
</TouchableOpacity>
</View>
</View>
</ImageBackground>
</View>
);
}
}
When I navigate to the 'StepTwo' screen after the fetch call, there is no response. I can't navigate to the next screen. It is like the navigate call inside the fetch is not working. Can anyone help me to solve this problem ?
And one more thing. Is the any fault in my code ? Since i am new to react native, i have no idea what I am writing is correct or not. Maybe regarding the this. something element.
I give another example (App.js):
import React from 'react';
import { StyleSheet, Text, View, TouchableOpacity } from 'react-native';
import { StackNavigator } from 'react-navigation';
import Expo from 'expo';
import HomeScreen from './app/screens/HomeScreen';
import LoginScreen from './app/screens/LoginScreen';
import RegisterScreen from './app/screens/RegisterScreen';
const NavigationApp = StackNavigator({
Home: { screen: HomeScreen },
Login: { screen: LoginScreen },
Register: { screen: RegisterScreen },
});
export default class App extends React.Component {
render() {
return (
<NavigationApp />
);
}
}
Then Login file (Login.js)
import React, { Component } from 'react';
import { Text, View, StyleSheet, ImageBackground, TextInput, TouchableOpacity, Alert } from 'react-native';
import { FormLabel, FormInput } from 'react-native-elements'
export default class Login extends Component {
static navigationOptions = {
header: null
};
constructor(props) {
super(props);
this.state = {
userName : '',
userPass : ''
}
}
login = () => {
const {userName} = this.state;
const {userPass} = this.state;
if(userName == '' || userPass == '') {
Alert.alert('Warning' , 'Please Insert All the Required Details !!!!');
} else {
let url = 'loginProcessGetUserDetails.jsp?';
let param_one = 'user_name='+userName;
let param_two = 'user_pass='+userPass;
let param_three = 'user_group=JOMLOKA';
let seperator_param = '&';
let full_url = '';
full_url = url + param_one + seperator_param + param_two + seperator_param + param_three;
let header = {
'Accept': 'application/json',
'Content-Type': 'application/json'
};
fetch( full_url, {
method: 'GET',
headers: header,
})
.then(function(response) {
return response.json();
})
.then(function(myJson) {
console.log(myJson);
if(myJson.message == 'No User') {
Alert.alert('Warning' , 'No User !!!!');
} else if (myJson.message == 'Wrong Password') {
Alert.alert('Warning' , 'Wrong Password !!!!');
} else if (myJson.message == 'Login') {
//Alert.alert('Success' , 'Login !!!!');
const { navigate } = this.props.navigation;
navigate("Register",{ userEmail: this.state.userEmail , userPhone: this.state.userPhone });
}
});
}
}
render() {
const { navigate } = this.props.navigation;
return (
<View style={styles.container}>
<ImageBackground source={require('../img/background1.jpg')} style={styles.backgroundImage}>
<View style={styles.content}>
<Text style={styles.logo}> -- LOGIN DEMO -- </Text>
<View style={styles.inputContainer}>
<TextInput underlineColorAndroid='transparent' style={styles.input} placeholder='ENTER USERNAME' onChangeText = {userName => this.setState({userName})} >
</TextInput>
<TextInput underlineColorAndroid='transparent' secureTextEntry={true} style={styles.input} placeholder='ENTER PASSWORD' onChangeText = {userPass => this.setState({userPass})} >
</TextInput>
</View>
<View style={styles.buttonHolder}>
<TouchableOpacity onPress={this.login} style={styles.buttonContainer}>
<Text style={styles.buttonText}>LOGIN</Text>
</TouchableOpacity>
<TouchableOpacity onPress={ ()=> navigate('Home') } style={styles.buttonContainer}>
<Text style={styles.buttonText}>CANCEL</Text>
</TouchableOpacity>
</View>
</View>
</ImageBackground>
</View>
);
}
}
That is another example with the same problem.
Replace
onPress={ this.moveToStepTwo }
with
onPress={()=> this.moveToStepTwo() }
this.props.navigation.navigate('StepTwo', { userEmail: this.state.userEmail , userPhone: this.state.userPhone } );
Are you sure your this is correct?
If you don't use Arrow Function, you need to do this var _this = this, then _this.props.navigation.navigate('StepTwo', { userEmail: this.state.userEmail , userPhone: this.state.userPhone } );
You can use Arrow functiom in fetch:
fetch(url, options)
.then(response => {
// ...
})
.catch(error => {
// ...
})
I assume that you have installed react-navigation plugin.
Now import your files in the app.js
like below :
import login from './login';
import StepTwo from './StepTwo';
const Nav = StackNavigator({
login : {screen: login},
StepTwo : {screen: StepTwo},
});
export default class FApp extends Component {
render() {
return (
<Nav/>
);
}
}
And in your login file. (Considering your this file as a login file)
if(myJson.message == 'No User') {
const { navigate } = this.props.navigation;
navigate("StepTwo",{ userEmail: this.state.userEmail , userPhone: this.state.userPhone });
} else if (myJson.message == 'Got User') {
Alert.alert('Warning' , 'Email is registered, Choose different email !!!!');
}

JSON Parse error: Unable to parse JSON string in React Native

I am having trouble trying the parse this JSON data. I can fix this error by limiting my data to just one like this: {"id": "13", "imagename": "hello"}, but this is my whole data:
{"id":"1","imagename":"dog"}{"id":"2","imagename":"cat"}{"id":"3","imagename":"mouse"}{"id":"4","imagename":"deer"}{"id":"5","imagename":"shark"}{"id":"6","imagename":"ant"}
I think React Native cannot handle no more than one data in <Text>?
export default class HomeScreen extends React.PureComponent {
constructor(props)
{
super(props);
this.state = {
isLoading: true,
};
componentDidMount(){
fetch(`http://www.example.com/React/data.php`, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
}).then((response) => response.json())
.then((responseJson) => {
data = responseJson;
this.setState({ loading: false });
}).catch((error) => {
console.warn(error);
});
}
renderItems() {
const items = [];
this.data.foreach( ( dataItem ) => {
items.put( <Text>{ dataItem.id }</Text> );
} )
return items;
} <--- This is an attempt to try to put them in an object and then display the data, but I keep getting undefined.
render() {
if (this.state.isLoading) {
return (
<View style={{flex: 1, paddingTop: 20}}>
<ActivityIndicator />
</View>
);
}
return(
<View style = { styles.MainContainer }>
<View>
<Card>
<View>
<Text>{this.data.id}</Text>
<Text>{this.data.imagename}</Text>
</View>
</Card>
</View>
</View>
);
}
const styles = StyleSheet.create({
MainContainer: {
flex:1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#333',
},
}
I also looked up other parse error questions, but our code is very different. Like I said before, this code works if the data is limited to one. I can't figure out why it does not allow more than one data to be displayed.
EDIT: When I changed my response.json to text, I got no results so that could be a reason. When I changed <Text>{this.data.id}</Text> to just this.data, I can see all of the data. How do I get just the id from that data?
You can write the JSON as the notation of an object, containing an array, containing objects:
'{"images" : [{"id":"1", "imagename":"dog"},{"id":"2", "imagename":"cat"},{"id":"3", "imagename":"mouse"},{"id":"4", "imagename":"deer"},{"id":"5", "imagename":"shark"},{"id":"6", "imagename":"ant"}]}'

React Native Fetch works only on second click

I do app on React Native. The problem is next :
OnPress some element i am trying make request to my server and log answer.
When I click button first time - my log do not show anything , but on second click I see response in the console.
import React from 'react'
import { View, Text, StyleSheet, TextInput , TouchableNativeFeedback , AsyncStorage } from 'react-native'
import {connect} from 'react-redux'
import * as pageActions from '../action/index'
import { bindActionCreators } from 'redux'
import api from '../api'
class Login extends React.Component {
constructor(props){
super(props);
this.state = {
loginAttempt : false,
email : 'admin#mail.ru',
password : 'password',
token : ''
}
}
loginAttempt() {
let email = this.state.email;
let password = this.state.password;
api.login(email,password)
}
render() {
return (
<View style={styles.container}>
<TextInput
placeholder="Email"
style={{height: 50, borderColor: 'gray', borderWidth: 1}}
onChangeText={(value) => this.setState({email : value})}
/>
<TextInput
placeholder="Password"
style={{height: 50, borderColor: 'gray', borderWidth: 1}}
onChangeText={(value) => this.setState({password : value})}
/>
<TouchableNativeFeedback
style={!this.state.loginAttempt ? {'opacity' : 1} : {'opacity' : 0}}
onPress={() => this.loginAttempt()}>
<View>
<Text>Try login</Text>
</View>
</TouchableNativeFeedback>
</View>
)
}
}
var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
}
}
)
My fetch function
login(email,password, callback) {
const API_HEADERS = {
'Accept' : `application/json`,
'Content-Type' : `application/json`
};
let user = {};
user.email = email;
user.password = password;
fetch(`http://myIp:3000/auth/login`, {
method : 'post',
headers : API_HEADERS,
body : JSON.stringify(user)
})
.then((response) => {
if (response.ok) {
return response.json();
} else {
alert(`Wrong data`)
}
})
.then((responseData) => {
console.log(responseData)
})
}
Also wanna add that I using Genymotion as android emul.Another strange thing is that when I press my button first time - nothing happens,but when i press Reload JS , before the component will be unmount , I see my responceData in a console
You should update state, when promise resolved.
.then((responseData) => {
this.setState({
token: responseData.token
});
})
Use catch method:
.then().catch(e => console.log("error: ", e))
Also, where is your alert function? react-native has Alert module.
Alert.alert('any message text');
article about fetch
and this is article using fetch in react-native
Another strange thing is that when I press my button first time
This is very like related to focus.
Try setting keyboardShouldPersistTaps = true for TouchableNativeFeedback

Resources