The localhost api can not be fetched from the expo - reactjs

The localhost api can not be fetched from the expo.
const search = async(type) => {
let response = await fetch(http://localhost:3000/api/${type}, {
accept: 'application/json'
});
let result = await response.json();
return result;
}
const create = async(type, data) => {
let response = await fetch(http://localhost:3000/api/${type}, {
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
method: 'post',
body: JSON.stringify(data)
});
let result = await response.json();
return result;
}
const Client = {search, create};
export default Client;
Client.js
const search = async(type) => {
let response = await fetch(`http://localhost:3000/api/${type}`, {
accept: 'application/json'
});
let result = await response.json();
return result; }
const create = async(type, data) => {
let response = await fetch(`http://localhost:3000/api/${type}`, {
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
method: 'post',
body: JSON.stringify(data)
});
let result = await response.json();
return result;
}
const Client = {search, create};
export default Client;
App.js
import React, { Component } from 'react';
import {
Text,
View,
TextInput,
Button,
StyleSheet
} from "react-native";
import Client from './Client.js';
class App extends Component {
constructor() {
super()
this.state = {
users: [] // user에 대한 정보를 담기 위한 state
}
this.handleUserInputChange = this.handleUserInputChange.bind(this)
}
componentWillMount = () => {
this.getUser()
}
handleUserInputChange = event => {
const {target: {name, value}} = event
this.setState({
[name]: value
});
}
getUser = async() => {
Client.search('User') // Client.js에서
.then(data => {
this.setState({
users: data
})
})
}
submitUser = () => {
const data = {
"$class": "org.acme.model.User",
"phonenumber": this.state.phonenumber,
"email": this.state.email,
"firstName": this.state.firstName,
"lastName": this.state.lastName,
}
Client.create('User', data)
.then(() => {
this.getUser()
})
}
render() {
return(
<View className="App">
<Text>Add User</Text>
<Text>phonenumber:</Text>
<TextInput
onChange={this.handleUserInputChange}
type="text"
name="phonenumber" />
<Text>email:</Text>
<TextInput
onChange={this.handleUserInputChange}
type="text"
name="email" />
<Text>firstName:</Text>
<TextInput
onChange={this.handleUserInputChange}
type="text"
name="firstName" />
<Text>lastName:</Text>
<TextInput
onChange={this.handleUserInputChange}
type="text"
name="lastName" />
<Button title="New User" onPress={()=> this.submitUser}/>
<View style={styles.container}>
<Text style={styles.userlist}>
User List
</Text>
{this.state.users.map((r, i) => (
<View style={styles.userstate}
key={i}>
<Text>phonenumber: {r.phonenumber}</Text>
<Text>email: {r.email}</Text>
<Text>firstName: {r.firstName}</Text>
<Text>lastName: {r.lastName}</Text>
</View>
))}
</View>
</View>
)
}
}
const styles=StyleSheet.create({
container: {
flex:1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
userlist:{
fontSize: 20,
textAlign: 'center',
margin: 10,
},
userstate:{
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
});
export default App;

The error is logical, because "localhost" is the name that designates a logical interface of the local computer.
So when you ask your application to make a request to "http://localhost:3000/api", it sends the request to the phone so it will never reach your computer.
But if your local network allows it, you can put directly the IP address of your computer.

You have to expose your APIs. One way you can do this is by using ngrok.
Try the below:
https://ngrok.com/ and follow the steps for installation after signing up
After unzipping open terminal and ./ngrok http <port_number>
If it is working, you should see a Forwarding: <forwarding_address>
Copy this forwarding address as your base url in the app
Just to test, try hitting this forwarding address in your browser, ex. http://1a6b3022.ngrok.io/api/testing you should get a response
Hopefully this is helpful!

Related

Square CreditCard payment in Reactjs

I am trying to integrate react-square-web-payments-sdk , Need to add creditcard holder name field in the paymentform and how can i mention the amount to be deducted from card to do that please check the below code and let me know still i need to add anything more.
I have installed react-square-web-payments-sdk and added creditCard in paymentform and getting the fields like cardnumber, mm/yy, cvv. and zipcode, But i need Cardholder name and no need of zip code, How can i do that and from my below code how can i show how much money to be deducted. Below is my component.
const Payment = () => {
const [errorMessage, setErrorMessage] = useState(null);
const onNonceGenerated = async (error, nonce) => {
if (error) {
setErrorMessage(error.message);
return;
}
// Your code to process the payment
try {
// Call your server to process the payment
const response = await fetch("/process-payment", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ nonce }),
});
console.log(response, "resp");
if (!response.ok) {
throw new Error("Failed to process payment");
}
// Payment was successful
alert("Payment successful!");
} catch (error) {
setErrorMessage(error.message);
}
};
return (
<div className="container">
{errorMessage && <p>{errorMessage}</p>}
<PaymentForm
applicationId="sandbox-Id"
locationId="locationId"
cardTokenizeResponseReceived={async (token, verifiedBuyer) => {
console.log(token,"token");
console.log(verifiedBuyer,"verifiedBuyer");
const response = await fetch("/api/pay", {
method: "POST",
headers: {
"Content-type": "application/json",
},
body: JSON.stringify({
sourceId: token.token,
}),
});
console.log(await response.json());
}}
>
<CreditCard
buttonProps={{
css: {
backgroundColor: "#E56B6F",
fontSize: "14px",
color: "#fff",
"&:hover": {
backgroundColor: "#E56B6F",
},
},
}}
/>
</PaymentForm>
</div>
);
};

React Native Axios -> wait for async response and navigate to new page if true

I am sending a POST with user credentials with axios in an React-Native App:
const LoginScreen = ({ navigation }) => {
const [user, setUser] = useState('');
const [pass, setPass] = useState('');
async function onLoginPress() {
await sendtoapi(user, pass);
if(login==true){
alert('Success, redirect to Details')
navigation.navigate('Details');
}
;}
return (
<View style={{ flex: 1, alignItems: 'center'}}>
<Text style={styles.logoText}>App</Text>
<TextInput placeholder="Username" placeholderColor="#c4c3cb" style={styles.loginFormTextInput} onChangeText={user => setUser(user)} />
<TextInput placeholder="Password" placeholderColor="#c4c3cb" style={styles.loginFormTextInput} secureTextEntry={true} onChangeText={pass => setPass(pass)}/>
<Button
buttonStyle={styles.loginButton}
onPress={() => onLoginPress()}
title="Login"
/>
</View>
);
};
this is the axios function (sendtoapi):
async function sendtoapi(user, pass){
var data = JSON.stringify({"user":user,"pass":pass});
var config = {
method: 'post',
url: 'http://localhost/api/dev/',
headers: {
'Content-Type': 'application/json'
},
data : data
};
axios(config)
.then(function (response) {
var res = response.data;
if(res.login==true){
login = true;
}
})
.catch(function (error) {
console.log(error);
});
}
Basically this code works, but I have to hit the "Login" Button twice, because it seems that the var login is not set to true after await sendtoapi(user, pass); so it is not waiting. What could couse this problem?
It is not a matter of double click in order to get the value, your sendtoapi function is not returning a Promise (that is related to the network request).
Refactor your code so it will return axios's Promise, then the code that handles the global login param will run only after the server response.
function sendtoapi(user, pass) {
var data = JSON.stringify({ user: user, pass: pass });
var config = {
method: 'post',
url: 'http://localhost/api/dev/',
headers: {
'Content-Type': 'application/json',
},
data: data,
};
// --∨ this is required in order to the outer `await` will wait for the network request
return axios(config)
.then(function (response) {
var res = response.data;
return { isLoggedIn: res.login }; // it is better to return your "promised" value to the consumer
})
.catch(function (error) {
console.log(error);
});
}
small refactor to the consumer code
const LoginScreen = ({ navigation }) => {
const [user, setUser] = useState('');
const [pass, setPass] = useState('');
async function onLoginPress() {
const { isLoggedIn } = await sendtoapi(user, pass);
// ---------^ the value which your promise returns
if (isLoggedIn === true) {
alert('Success, redirect to Details');
navigation.navigate('Details');
}
}
return (
<View style={{ flex: 1, alignItems: 'center' }}>
<Text style={styles.logoText}>App</Text>
<TextInput
placeholder="Username"
placeholderColor="#c4c3cb"
style={styles.loginFormTextInput}
onChangeText={(user) => setUser(user)}
/>
<TextInput
placeholder="Password"
placeholderColor="#c4c3cb"
style={styles.loginFormTextInput}
secureTextEntry={true}
onChangeText={(pass) => setPass(pass)}
/>
<Button buttonStyle={styles.loginButton} onPress={() => onLoginPress()} title="Login" />
</View>
);
};
Tip: don't use global / module vars for such tasks since it will be hard to expose it to the rest of the app.
I recommend you to store it on some react related storage (context / state).

Access object in JSON array with this.state in React Native

I am having trouble displaying an object from an array. I want to display id from here:
[
{
"id":"1",
"imagename":"dog"
},
{
"id":"2",
"imagename":"cat"
},
{
"id":"3",
"imagename":"mouse"
},
{
"id":"4",
"imagename":"deer"
},
{
"id":"5",
"imagename":"shark"
},
{
"id":"6",
"imagename":"ant"
}
]
Here is my attempt:
fetch(`http://www.example.com/React/data.php` , {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
}
})
.then((response) => response.json())
.then((responseJson) => {
this.setState({
isLoading: false,
dataSource: responseJson,
id: responseJson[0].id, <-- Attempt to try to get the id from responsejson.
},function() {
// In this block you can do something with new state.
});
})
.catch((error) => {
console.error(error);
});
With this I got undefined is not a function. I am not getting what I am doing wrong or how to access this object.
<FlatList
data={ this.state.dataSource}
ItemSeparatorComponent = {this.FlatListItemSeparator}
renderItem={({item}) => <View>
<Card>
<View>
<Text style={{marginTop: 30}}> {this.state.responseJson.id}</Text>
</View>
</Card>
</View>
}
keyExtractor={(item, index) => index.toString()}
/>
Try the async/await method, you are getting an error because the data is not load and the render function is trying to load the data.
async componentDidMount() {
await fetch(`http://www.example.com/React/data.php`, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
}
}).then((response) => response.json()).then((responseJson) => {
this.setState({
isLoading: false,
dataSource: responseJson,
id: responseJson[0].id
});
}).catch((error) => {
console.error(error);
});
}
Or another approach is to add a loading preloader or spinner like this.
First import the package.
import { ActivityIndicator } from 'react-native';
Second change the render method
render() {
if (isLoading) {
return ( <
View style = {
[styles.container, styles.horizontal]
} >
<
ActivityIndicator size = "large"
color = "#0000ff" / >
<
/View>
);
}
return (
// Your render stuffs
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center'
},
horizontal: {
flexDirection: 'row',
justifyContent: 'space-around',
padding: 10
}
})
If any issue please let me know

React Native image upload

I am having an issue with uploading an image from my camera roll or to my API. here is the code that I am currently using. I am able to get the image data from both the camera roll and camera. I just am having an issue of posting the data to the server. I don't know where I am getting confused.
import React, { Component } from 'react';
import {
Text,
View,
PixelRatio,
TouchableOpacity,
Image,
Platform,
NativeModules,
DeviceEventEmitter
} from 'react-native';
import { connect } from 'react-redux';
import ImagePicker from 'react-native-image-picker';
import { captureProflieAvitar } from '../../actions';
var RNUploader = NativeModules.RNUploader;
class NewCamera extends Component {
state = {
avatarSource: null,
imgBase64: []
}
componentDidMount() {
// upload progress
DeviceEventEmitter.addListener('RNUploaderProgress', (data) => {
const bytesWritten = data.totalBytesWritten;
const bytesTotal = data.totalBytesExpectedToWrite;
const progress = data.progress;
console.log(bytesWritten, bytesTotal);
console.log( "upload progress: " + progress + "%");
});
}
selectPhotoTapped() {
const options = {
quality: 0.75,
maxWidth: 300,
maxHeight: 300,
storageOptions: {
skipBackup: true
}
};
ImagePicker.showImagePicker(options, (response) => {
console.log('Response = ', response);
if (response.didCancel) {
console.log('User cancelled photo picker');
} else if (response.error) {
console.log('ImagePicker Error: ', response.error);
} else if (response.customButton) {
console.log('User tapped custom button: ', response.customButton);
} else {
let source;
// You can display the image using either:
source = { uri: 'data:image/jpeg;base64,' + response.data, isStatic: true };
const temp = response.data;
//Or:
if (Platform.OS === 'android') {
source = { uri: response.uri, isStatic: true };
} else {
source = { uri: response.uri.replace('file://', ''), isStatic: true };
}
this.setState({
avatarSource: source,
imgBase64: temp,
});
}
});
}
doUpload() {
const files = {
filepath: `data:image/png;base64,${this.state.imgBase64}`,
};
const opts = {
url: 'https://central.tipflip.co?apior=MYAPIKEY&tfReqID3031&tfUserID=1&tfImage=',
files,
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
};
RNUploader.upload(opts, (err, response) => {
if (err) {
console.log(err);
return;
}
const status = response.status;
const responseString = response.data;
const json = JSON.parse(responseString);
console.log('upload complete with status ' + status);
});
}
render() {
return (
<View style={styles.container}>
<TouchableOpacity onPress={this.selectPhotoTapped.bind(this)}>
<View style={[styles.avatar, styles.avatarContainer, { marginBottom: 20 }]}>
{ this.state.avatarSource === null ? <Text>Select a Photo</Text> :
<Image style={styles.avatar} source={this.state.avatarSource} />
}
</View>
</TouchableOpacity>
<TouchableOpacity
style={{
backgroundColor: 'yellow',
width: 60,
height: 20,
marginTop: 20,
justifyContent: 'center',
alignItems: 'center' }}
onPress={this.doUpload.bind(this)}
>
<Text>Upload</Text>
</TouchableOpacity>
<TouchableOpacity
style={{
backgroundColor: 'yellow',
width: 60,
height: 20,
marginTop: 20,
justifyContent: 'center',
alignItems: 'center'
}} onPress={this.props.cancel}
>
<Text>Cancel</Text>
</TouchableOpacity>
</View>
);
}
}
const styles = {
container: {
justifyContent: 'center',
alignItems: 'center'
},
avatarContainer: {
borderColor: '#9B9B9B',
borderWidth: 1 / PixelRatio.get(),
justifyContent: 'center',
alignItems: 'center'
},
avatar: {
borderRadius: 75,
width: 150,
height: 150
}
};
export default connect(null, { captureProflieAvitar })(NewCamera);
Here is example to upload image using Fetch API
var photo = {
uri: user.profilePicture,
type: 'image/jpeg',
name: 'photo.jpg',
};
var form = new FormData();
form.append("ProfilePicture", photo);
fetch(
Constants.API_USER + 'me/profilePicture',
{
body: form,
method: "PUT",
headers: {
'Content-Type': 'multipart/form-data',
'Authorization': 'Bearer ' + user.token
}
}
).then((response) => response.json())
.catch((error) => {
alert("ERROR " + error)
})
.then((responseData) => {
alert("Succes "+ responseData)
}).done();
Credits
https://stackoverflow.com/a/36649457/5315786
If anyone trying to upload an image to Laravel using React Native try this. my case i'm using react-native-image-crop-picker with Axios
//create object with uri, type, image name
var photo = {
uri: IMAGE_PATH,
type: 'image/jpeg',
name: 'photo.jpg',
};
//use formdata
var formData = new FormData();
//append created photo{} to formdata
formData.append('image', photo);
//use axios to POST
axios({
method: 'POST',
url: api_url + 'customer/upload-avatar',
data: formData,
headers: {
'Authorization': "Bearer " + YOUR_BEARER_TOKEN,
'Accept': 'application/json',
'Content-Type': 'multipart/form-data;'
}}) .then(function (response) { console.log(response)})
.catch(function (error) { console.log(error.response)
});
if you use react-native-image-picker and try to upload your image on laravel restful API, try this.
// create a state for temp photo
const [photo, setPhoto] = React.useState(null);
// create a function to set a temp photo
const handleChoosePhoto = () => {
launchImageLibrary({noData: true}, (response) => {
if (response && !response.didCancel) {
setPhoto(response);
}
});
};
// create a function to post your temp photo through api
const setData = () => {
const formData = new FormData();
if (photo) {
const tempPhoto = {
uri: photo?.assets[0]?.uri,
type: photo?.assets[0]?.type,
name: photo?.assets[0]?.fileName,
};
formData.append('avatar', tempPhoto);
axios({
method: 'POST',
url: api_url + 'api/upload-avatar',
data: formData,
headers: {
'Authorization': "Bearer " + YOUR_BEARER_TOKEN,
'Accept': 'application/json',
'Content-Type': 'multipart/form-data;'
}})
.then((response) => {
console.log(response)
})
.catch((error) => {
console.log(error.response)
});
}
}

Connect two modal picker in react native

I use react native modal picker to drop down the data link here
I used two modal picker, that depend on each other. first one is select service. second one is select city. I want to display cities that have particular services. code is here
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
Alert,
TouchableHighlight,
Image,
TextInput,
} from 'react-native';
var fullservice=[];
var citylist=[];
import ModalPicker from 'react-native-modal-picker'
class jsonSugei extends Component {
constructor() {
super();
this.state = {
textInputValue: '',
dropdownservices:[],
city:'',
dropdowncities:[],
service:'',
}
}
componentDidMount() {
this.fetchData1();
this.fetchData2();
}
fetchData1(){
fetch("URL",
{method: "POST",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify( {"cacheRequest":["ALL_COMPANY","ALL_SERVICE","HOT_COMPANY","BANNER","PARTNER","CITY","CALANDAR","COMMENTS "]}),
})
.then((response) => response.json())
.then((responseData) => {
this.setState({
dropdownservices: responseData.services,
});
})
.catch((error) => { console.warn(error); })
.done();
}
fetchData2(){
this.state = {
service:'',
}
fetch("URL",
{method: "POST",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify( {
"companyId":"",
"service":this.state.service,
"key":""
}),
})
.then((response) => response.json())
.then((responseData) => {
this.setState({
dropdowncities: responseData.cities,
});
})
.catch((error) => { console.warn(error); })
.done();
}
render() {
citylist= this.state.dropdowncities.map(function(item) {
return {
key:item.id,
label: item.name,
};
});
fullservice =this.state.dropdownservices.map(function(item) {
return {
key:item.id,
label: item.name,
};
});
return (
<View style={{flex:1, justifyContent:'space-around', padding:50, backgroundColor: '#ffffff'}}>
<ModalPicker1
data={fullservice}
initValue="Select Services!"
onChange={(option)=>{this.setState({service:option.label})}}
/>
<ModalPicker
style={{marginTop:10}}
data={citylist}
initValue="City"
onChange={(option)=>{ this.setState({city:option.label})}}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: '#ffffff',
},
button: {
borderRadius: 4,
padding: 10,
marginLeft: 10,
marginRight: 10,
backgroundColor: "#B8C",
},
});
AppRegistry.registerComponent('jsonSugei', () => jsonSugei);
but not change cities according to the services??? I need help............
The onChange event handler for services ModalPicker should set the state for the cities ModalPicker. Also, the initial fetch for the cities ModalPicker should only fetch cities corresponding to the default service.
Add another function to first modal picker, and set the data entity as a get state variable,
<ModalPicker1 data={fullservice} initValue="Select Services!" onChange={(option)=>{this.setState({service:option.label}),this.secondFunction()}} />
Then set the state.cities variable in the second function and use it as the data entity in second modal picker,
secondFunction(){
this.setState({cities:array});
}
<ModalPicker2 data={this.state.cities} initValue="City" onChange={(option)=>{this.setState({city:option.label})}} />

Resources