How to display the users_ID on the screen with react native - php

I made login with PHP and React Native but now I want to display the ID of the user that's logged in. The ID should be showed on the screen that appears when the user is logged in.
I tried several things but I think the way I request the props is wrong. Because the page where I want to show never requests the data that is started in the previous page.
This is the login screen:
import React from 'react';
import { StyleSheet, Text, View, TextInput, Button } from 'react-native';
import * as Expo from 'expo';
export default class App extends React.Component {
state = {
username: '',
password: '',
response: '',
users_ID: '',
};
handleusers_usernameChange = (users_username) => {
this.setState({ users_username });
};
handleusers_passwordChange = (users_password) => {
this.setState({ users_password });
};
handleLoginPress = async () => {
const { users_username, users_password } = this.state;
try {
let response = await fetch('http://IP/CodingApp/login.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
users_username,
users_password,
}),
});
let responseJson = await response.json();
console.log(responseJson);
if (responseJson.loggedin) {
this.props.setLoggedIn(true, responseJson.users_ID);
this.setState({ users_ID: responseJson.users_ID });
} else {
this.setState({ response: 'tekst kwam niet overeen' });
}
} catch (error) {
console.error(error);
}
};
render() {
return (
<View style={styles.container}>
<TextInput
style={styles.input}
value={this.state.users_username}
onChangeText={this.handleusers_usernameChange}
placeholder="users_username"
/>
<TextInput
style={styles.input}
value={this.state.users_password}
onChangeText={this.handleusers_passwordChange}
placeholder="users_password"
secureTextEntry
/>
<Button title="Login" onPress={this.handleLoginPress} />
<Text>{this.state.response}</Text>
</View>
);
}
}
And this is the screen that appears after the user is logged in:
import React from 'react';
import { View, Text } from 'react-native';
const EditFamily = (props) => {
return (
<View>
<Text>Your user ID is: {props.users_ID}</Text>
</View>
);
};
export default EditFamily;

Read about redux, which is a state management tool, you can save id whenever or wherever you go and use it everywhere.
https://redux.js.org/introduction/getting-started

Related

react native 403 permission error from php api on wamp server

react native error
import React, { Component } from 'react';
import { ActivityIndicator, FlatList, Text, View } from 'react-native';
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
data: [],
isLoading: true
};
}
async getMovies() {
try {
const response = await fetch('http://192.168.1.6:80/p4Lite/Sept2021/react_backend/index.php');
const json = await response.json();
this.setState({ data: json });
} catch (error) {
console.log(error);
} finally {
this.setState({ isLoading: false });
}
}
componentDidMount() {
this.getMovies();
}
render() {
const { data, isLoading } = this.state;
return (
<View style={{ flex: 1, padding: 24 }}>
{isLoading ? <ActivityIndicator/> : (
<FlatList
data={data}
keyExtractor={({ id }, index) => id}
renderItem={({ item }) => (
<Text>{item.name}, {item.email}</Text>
)}
/>
)}
</View>
);
}
};
Above is my app.js file code. It works fine on web but shows error on my android phone using expo go. I have tried various methods but till now is solution fond. I am working on localhost.
Try this on your API related folder
sudo chmod -R -f 777 /path/to/your/file/or/directory
the 403 error means that the request you made was forbidden. it is generally received when a required password is not entered.
Most likely, your API requires a password, and this was not provided by the code, the server code is miss-configured, or the server does not have the right permissions to display the result.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/403
Some how it's working by changing:
Require local to Require all granted in httpd-vhosts.conf

post/passing data array in react native using axios not caught by ENDPOINT

i'm trying to make simple CRUD using axios in react-native, when i'm trying to create an add data function i'm having problems passing array data to endpoint,
note: the endpoint I created using php native,
I've tried my endpoint using POSTMAN 3 times, and it worked.
enter image description here
however, when I try to POST using axios in react native, the data in the array is not caught by the endpoint.
import React, { Component } from 'react'
import { Text, View, StyleSheet, TextInput, TouchableOpacity, Alert } from 'react-native'
import axios from 'axios'
export class CreatelData extends Component {
constructor(props) {
super(props)
this.state = {
title:'',
description: '',
}
}
onSubmit = () => {
const dataInput = {
title: this.state.title,
description: this.state.description,
}
console.warn(dataInput)
axios.post('http://my_local_ip/fullstack/smooth_test/backend/api.php?on=create', dataInput)
.then( response => {
// resultSend(response.data)
console.log('res: ', response.data)
})
.catch(err => console.log('err: ', err) )
}
render() {
return (
<View style={tampilan.container}>
<Text style={tampilan.header}>POST</Text>
<View>
<View style={tampilan.row}>
<Text>Title :</Text>
<TextInput
style={tampilan.textInput}
placeholder="Enter Title..."
onChangeText= { (value) => {this.setState( {title: value} )} }
></TextInput>
</View>
<View style={tampilan.row}>
<Text>Description :</Text>
<TextInput
style={tampilan.textInputArea}
placeholder="Enter Description..."
onChangeText= { (value) => {this.setState( {description: value} )} }
></TextInput>
</View>
<View style={tampilan.row}>
<TouchableOpacity
style={tampilan.btnSubmit}
onPress={ () => this.onSubmit() }
>
<Text style={tampilan.textbtn}>Submit</Text>
</TouchableOpacity>
</View>
</View>
</View>
)
}
}
however, when I try to view the array using console.warm(data), the data has contents, and is not empty.
enter image description here
anyone please advice and solutions..
I found some help here react native axios
axios post look like this :
const user = {
name: this.state.name
};
axios.post(`https://jsonplaceholder.typicode.com/users`, { user })
.then(res => {
console.log(res);
console.log(res.data);
})
then your code code could be look like this
const dataInput = {
title: this.state.title,
description: this.state.description,
}
console.warn(dataInput)
axios.post('http://my_local_ip/fullstack/smooth_test/backend/api.php?on=create', {dataInput})
.then( response => {
// resultSend(response.data)
console.log('res: ', response.data)
})

how to check if a new record has been added to a database in php and covert it to react native (Notification message)

I am new to react native and I am creating an app that displays a list fo podcasts which are stored in a mysql database. I then use php to get the information and convert it to json format. Once the information is covered to json I then fetch it within react native and display it within a flatlist.
I would like a notification to appear each time the podcast list has been update.
I have set up my notifications using onesignal and use node.js on my backend to create and send the notifications.
I would like to be able to listen to the database to check each time that the database has a new row and then covert this into react native so that I can send the notifications.
After doing some research I have been unable to find a solution for this.
Here is my php
<?php
include 'DBConfig.php';
$json = file_get_contents('php://input');
$obj = json_decode($json, true);
$id = $obj['id'];
$query = "SELECT * FROM SermonsTable WHERE Category ='$id'";
$result = mysqli_query($con, $query) or die("Invalid Query");
while($row = mysqli_fetch_assoc($result)){
$Item[] = $row;
$json = json_encode($Item);
}
echo $json;
?>
React Native file
export default class MainScreen extends React.Component
{
constructor(props) {
super(props);
this.state = {
isLoading: true
}
}
componentDidMount(){
const fetch = require('node-fetch');
fetch('http://03d77927eb6d.ngrok.io/AntrimElimChurch/backend/FilterCat.php', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
// Getting the id.
id: this.props.navigation.state.params.FlatListClickItemHolder
})
}).then((response) => response.json())
.then((responseJson) => {
this.setState({
isLoading: false,
dataSource: responseJson
});
}).catch((error) => {
console.error(error);
});
}
FlatListViewItemSeparator = () => {
return (
<View
style={{
height: .5,
width: "100%",
backgroundColor: "#000",
}}
/>
);
}
OpenSecondActivity(id) {
this.props.navigation.navigate("Podcats", { FlatListClickItemHolder: id});
}
componentDidMount() {
this.dataSource.addEventListener('change', this.RunNotification);
}
RunNotification = () => {
fetch('http://localhost:8080/api', {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
}).then(res => {
console.log(res);
return res.json();
}).then(response => {
console.log(response)
this.data = response;
}).catch(error =>{
this.error = error.message || error.error;
});
};
render() {
if (this.state.isLoading) {
return (
<View style={{flex: 1, paddingTop: 20}}>
<ActivityIndicator />
</View>
);
}
return (
<View style={styles.MainContainer}>
<FlatList style={{paddingTop: 30}}
data={ this.state.dataSource }
ItemSeparatorComponent = {this.FlatListItemSeparator}
renderItem={this._renderItem}
keyExtractor={(item, index) => index.toString()} />
</View>
);
}
_renderItem = ({item}) => {
return(
<View style={styles.MainView}>
<View style={{flex: 1, flexDirection: 'row'}}>
<Text style={styles.rowViewContainer} onPress={this.OpenSecondActivity.bind(this, item.id)}>{item.Name}</Text>
{/* <Text style={styles.SermonByText}>{item.SermonBy}</Text> */}
<Text style={styles.PodcastByText}> - {item.DateRecorded}</Text>
</View>
</View>
);
}
}
I am really confused as to how to do this as I am new to react native and not that confident with php.
I recommend you to use sockets.
NPM socket.io is easy to use for front End
For your backend in PHP you can use this library https://github.com/walkor/phpsocket.io
So each time a new record has been added to your database you must use an handler to send a socket request to your client

how can i upload image using react native expo image to my local server PHP / Database MySQL

I'm making a mobile application using expo client to allow user to upload image or take from a camera and then the image saves on my local server on PHP / Database MySQL. How do I do that thing if I'm using an expo?
for example code in react native (saving to PHP local server but not save database)
import React, { Component } from 'react';
import {
ActivityIndicator,
Button,
Clipboard,
Image,
Share,
StatusBar,
StyleSheet,
Text,
TouchableOpacity,
View,
} from 'react-native';
import { Constants } from 'expo';
import * as ImagePicker from 'expo-image-picker';
import * as Permissions from 'expo-permissions';
export default class App extends Component {
state = {
image: null,
uploading: false,
};
render() {
let {
image
} = this.state;
return (
<View style={styles.container}>
<StatusBar barStyle="default" />
<Text
style={styles.exampleText}>
Example: Upload ImagePicker result
</Text>
<Button
onPress={this._pickImage}
title="Pick an image from gallery"
/>
<Button onPress={this._takePhoto} title="Take a photo" />
{this._maybeRenderImage()}
{this._maybeRenderUploadingOverlay()}
</View>
);
}
_maybeRenderUploadingOverlay = () => {
if (this.state.uploading) {
return (
<View
style={[StyleSheet.absoluteFill, styles.maybeRenderUploading]}>
<ActivityIndicator color="#fff" size="large" />
</View>
);
}
};
_maybeRenderImage = () => {
let {
image
} = this.state;
if (!image) {
return;
}
return (
<View
style={styles.maybeRenderContainer}>
<View
style={styles.maybeRenderImageContainer}>
<Image source={{ uri: image }} style={styles.maybeRenderImage} />
</View>
<Text
onPress={this._copyToClipboard}
onLongPress={this._share}
style={styles.maybeRenderImageText}>
{image}
</Text>
</View>
);
};
_share = () => {
Share.share({
message: this.state.image,
title: 'Check out this photo',
url: this.state.image,
});
};
_copyToClipboard = () => {
Clipboard.setString(this.state.image);
alert('Copied image URL to clipboard');
};
_takePhoto = async () => {
const {
status: cameraPerm
} = await Permissions.askAsync(Permissions.CAMERA);
const {
status: cameraRollPerm
} = await Permissions.askAsync(Permissions.CAMERA_ROLL);
// only if user allows permission to camera AND camera roll
if (cameraPerm === 'granted' && cameraRollPerm === 'granted') {
let pickerResult = await ImagePicker.launchCameraAsync({
allowsEditing: true,
aspect: [4, 3],
});
this._handleImagePicked(pickerResult);
}
};
_pickImage = async () => {
const {
status: cameraRollPerm
} = await Permissions.askAsync(Permissions.CAMERA_ROLL);
// only if user allows permission to camera roll
if (cameraRollPerm === 'granted') {
let pickerResult = await ImagePicker.launchImageLibraryAsync({
allowsEditing: true,
aspect: [4, 3],
});
this._handleImagePicked(pickerResult);
}
};
_handleImagePicked = async pickerResult => {
let uploadResponse, uploadResult;
try {
this.setState({
uploading: true
});
if (!pickerResult.cancelled) {
uploadResponse = await uploadImageAsync(pickerResult.uri);
uploadResult = await uploadResponse.json();
this.setState({
image: uploadResult.location
});
}
} catch (e) {
console.log({ uploadResponse });
console.log({ uploadResult });
console.log({ e });
alert('Upload failed, sorry :(');
} finally {
this.setState({
uploading: false
});
}
};
}
async function uploadImageAsync(uri) {
let apiUrl = 'http://192.168.0.18/upload-api/uploading.php';
let uriParts = uri.split('.');
let fileType = uriParts[uriParts.length - 1];
let formData = new FormData();
formData.append('fileToUpload', {
uri,
name: `fileToUpload.${fileType}`,
type: `image/${fileType}`,
});
let options = {
method: 'POST',
body: formData,
headers: {
Accept: 'application/json',
'Content-Type': 'multipart/form-data',
},
};
return fetch(apiUrl, options);
}
and here is my PHP
<?php
$target_dir = 'uploads/';
$target_file = $target_dir . basename($_FILES['fileToUpload']['name']);
$status = array();
if (move_uploaded_file($_FILES['fileToUpload']['tmp_name'], $target_file)) {
$status['status']=1;
$status['description']='upload success';
} else {
$status['status']=0;
$status['description']='upload failed';
}
echo json_encode($status);
?>
Any solution to this? thank you
You can use Fetch Api to upload image
var photo = {
uri: selectImg.localUri,
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();

Working with nested array in react native

I am making a quiz app in react native, I have written an API in PHP which fetches the question and the options from the database, with the response from API looking something like
[{"id":2109,
"title":"\u0915\u0930\u094d\u0923\u093e\u0932\u0940 \u0928\u0926\u0940\u0915\u094b \u0938\u0939\u093e\u092f\u0915 \u0928\u0926\u0940 \u0924\u0932\u0915\u093e \u092e\u0927\u094d\u092f\u0947 \u0915\u0941\u0928 \u0939\u094b\u0907\u0928 ?",
"option":[{
"option_id":191061,
"options":"\u0939\u0941\u092e\u094d\u0932\u093e \u0915\u0930\u094d\u0923\u093e\u0932\u0940",
"correct":0
},
{
"option_id":191062,
"options":"\u0920\u0942\u0932\u094b \u092d\u0947\u0930\u0940",
"correct":0},
{
"option_id":191060,
"options":"\u092e\u0941\u0917\u0941 \u0915\u0930\u094d\u0923\u093e\u0932\u0940",
"correct":0
},{
"option_id":191059,
"options":"\u0921\u094b\u0932\u094d\u092a\u093e \u0915\u0930\u094d\u0923\u093e\u0932\u0940",
"correct":1
}
]}]
................................
and so on,
Upto now I have successfully fetched the json in my react app as the way I like. But now I want to select only one option for each question, I want the option to be highlighted as per the user selection also I have to check if the user is correct or not by verifying with the json response.
How can I achieve this?
the full code is here:
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
TouchableHighlight,
Alert,
Navigator,
WebView,
ScrollView,
ListView
} from 'react-native';
export default class Api extends Component{
constructor(){
super()
this.state = {
id:'',
option_id:'',
option_option:[],
options_ans:[],
title:'',
data:[],
userSelectedIndex:-1,
}
}
componentWillMount(){
fetch('http://192.168.1.11/loksewaquiz/index.php? exam_of=kharidar', {method: 'GET'})
.then((response) => response.json())
.then((responseData) =>{
this.setState({
data:responseData,
})
})
.done();
}
onUserSelectedOption(index){
this.setState({
userSelectedIndex:index,
});
}
render(){
const result = this.state.data.map((data) =>{
const xx = data.ans_option.map((ans_option,index)=>{
return (
<TouchableHighlight onPress={()=> this.onUserSelectedOption(ans_option, index)}>
<Text key={ans_option.option_id} style={{backgroundColor: (index === this.state.userSelectedIndex) ? 'red' : 'transparent'}}> {ans_option.option_option}</Text>
</TouchableHighlight>
)
})
return(
<View>
<Text style={styles.titles}>{data.title}</Text>
{xx}
</View>
)
})
return(
<ScrollView>
{result}
</ScrollView>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection:'row',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
button:{
backgroundColor:'#EEE',
padding:10,
marginRight:5,
marginLeft:5,
},
options:{
padding:10,
marginRight:5,
marginLeft:5,
backgroundColor:'#EEE',
},
titles:{
backgroundColor:'#000',
color:'#FFF',
},
selectedoptions:{
backgroundColor:'#008000',
}
});
Here is the image when I select the first option
This is when I press the third option
Something like this , updated with one of the ways highlighting can be done
onUserSelectedOption = (option, index) => {
this.setState({
userSelectedIndex: index
});
if (option.correct === 1) {
//do something
}else {
//do something
}
}
render(){
const result = this.state.data.map((data) =>{
const xx = data.option.map((option, index)=>{
return (
<TouchableHighlight onPress={() => this.onUserSelectedOption(option, index)}>
<Text key={option.option_id} style={{backgroundColor: index === this.state.userSelectedIndex ? 'red' : 'transparent' }}>{option.options}</Text>
</TouchableHighlight>
)
})
return(
<View>
<Text style={styles.titles}>{data.title}</Text>
{xx}
</View>
)
})
return(
<ScrollView>
{result}
</ScrollView>
);
}
I would actually seperate the options in a new component, and pass relevant data via props. Not an expert on js, but sounds more solid then nested map functions.

Categories