react-native image upload with PHP server - php

can't upload images from react-native code to PHP server, however images are uploaded without any problem using postman, i suppose the problem isn't related with the server or the back end, but I'll provide the front end and back end code
I tried different libraries like react-native-document-picker and react-native-image-crop-picker but with no hope, so please could you tell me where exactly the problem is
PHP code
public function createApiImage(Request $request)
{
$attachment = [];
if ($request->attachments != null) {
$attachment = $request->attachments ;
$photo_name = 'ads';
$imgPath = $attachment->store("{$photo_name}", 'public');
$attachment1 =[
'type' => $attachment->getMimeType(),
'path' => $attachment->store("{$photo_name}", 'public'),
'name' => $attachment->getClientOriginalName(),
'created_at' => \Carbon\Carbon::now()
];
$imgPathUrl = 'http://dejara.net/storage/app/public/'.$imgPath;
$Mediadate = ['name' => "$imgPathUrl",'linked_id' => 0];
$media = Media::create($Mediadate);
}
return response()->json([
'success' => 'true',
'info' => [
'Media' => $media,
]
]
, 200
);
}
react-native code
import React, { Component } from 'react';
import ImagePicker from 'react-native-image-picker'
import { Text, View, TouchableOpacity, BackHandler, Image, ScrollView, Platform, ActivityIndicator, StatusBar, Dimensions } from 'react-native'
import { RFValue } from 'react-native-responsive-fontsize';
import FontAwesomeIcon from 'react-native-vector-icons/FontAwesome'
class PlaceAd extends Component {
state = {
pickedImages: []
}
pickImage = async () => {
ImagePicker.showImagePicker({ title: "choose your image" }, res => {
if (res.didCancel)
console.log('User cancelled')
else if (res.error)
console.log(res.error)
else {
// console.log(res)
let temp = this.state.pickedImages
temp.push({ uri: res.uri, name: res.fileName, type: res.type, path: res.path })
this.setState({ pickedImages: temp })
}
})
}
createAdv = () => {
var data = new FormData();
this.state.pickedImages.map((image, i) => {
data.append('my_photo', {
uri: image.uri,
path: image.uri,
name: image.name,
type: image.type,
})
})
fetch('http://dejara.net/public/api/createAdsImage', {
headers: {
'Accept': 'application/json',
'Content-Type': 'multipart/form-data'
},
method: 'POST',
body: data
})
.then(response => response.json())
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
}
render() {
return (
<View style={{width:'100%', alignItems:'center'}}>
<TouchableOpacity style={{ marginBottom: RFValue(20), marginTop: RFValue(10), width: RFValue(150), height: RFValue(150), justifyContent: 'center', alignItems: 'center', borderWidth: 1 }} onPress={this.pickImage}>
<FontAwesomeIcon name="photo" size={RFValue(20)} color="#000" />
<Text style={{ color: "#000" }}>choose photo</Text>
</TouchableOpacity>
<TouchableOpacity style={[{ width: '60%', height: RFValue(50), marginBottom: RFValue(15) }]} onPress={this.createAdv} >
<Text>Publish</Text>
</TouchableOpacity>
</View>
)
}
}
export default PlaceAd

I guess I found the problem do step by step and it may fix :
1- npm install form-data
2- import formData from 'from-data';
3- change var to const ===> const data = new FormData();
the most important thing is to install the form-data package to fix this issue
before that test your backend with postman to make sure it works properly and the problem is just about the fronend and follow that steps and i hope you fix it.

I got it, the server just waits for attachments
if ($request->attachments != null)
while i send my_photo instead
data.append('my_photo',
just changing my_photo to attachments solved my issue

Related

Laravel : Axios not saving the data in edit page

I create an edit page to edit the data. After the user edits the form. The form should be saved. But in my case I can't save the form it's showing error.
I facing this error.
ReminderComponent.vue
<script>
import Vue from 'vue'
import axios from 'axios'
import VueAxios from 'vue-axios'
import MarkdownIt from 'markdown-it'
import ClassicEditor from '#ckeditor/ckeditor5-build-classic';
var msg_editor;
Vue.use(VueAxios, axios);
const md = new MarkdownIt({
linkify: true
})
export default {
props: ['email_creation_link', 'email_index_route', 'email_edit_route','conditions','modules','mailtemplates'],
components: {
},
data() {
return {
template:
{
subject: '',
message: '' ,
days: '',
condition_id: 1,
},
options:[
{
display:'Client Name',
actual:'Client name'
},
{
display:'Joined Date',
actual:'Joined date'
},
{
display:'Module Name',
actual:'Module name'
},
{
display:'Last Seen',
actual:'Last seen'
},
],
showName: false,
}
},
mounted(){
var self = this;
ClassicEditor
.create(document.querySelector( "#msg"),
{
})
.then(editor => {
msg_editor = editor;
editor.model.document.on( 'change:data', () => {
self.template.message = msg_editor.getData();
});
})
.catch(error => {
console.error(error);
})
if (this.mailtemplates) {
this.template=this.mailtemplates;
}
},
methods: {
//Drag items
dragstart: function(item, e){
this.draggingItem = item;
e.dataTransfer.setData('text/plain', item.actual);
},
dragend: function(item,e) {
e.target.style.opacity = 1;
},
dragenter: function(item, e) {
this.draggingItem = item;
},
//content
replaceVariables(input)
{
let updated = input
return updated
},
//hidecontent
showHide: function(e)
{
console.log("Show "+e.target.value+ " fields")
this.showName = e.target.value !== ''
},
fetch()
{
//request data
axios.get(this.email_index_route,this.template)
.then((res) => {
this.template = res.data.template;
})
**axios.get(this.email_edit_route,this.mailtemplates)
.then((res) => {
this.mailtemplates = res.data.template;
})**
},
save()
{
//save data to db
axios.post(this.email_index_route, this.template)
.then((res) => {
alert('Mail sent successfull!')
})
**axios.post(this.email_edit_route, this.mailtemplates)
.then((res) => {
alert('Mail sent successfull!')
})**
},
addToMail: function(type, text)
{
if (type == 'message') {
this.template.message += text;
msg_editor.setData(this.template.message);
}
},
//user name replace
replaceVariables() {
return this.replaceVariables(this.options || '')
},
}
}
</script>
I think this area causing problem but i can't find the solution.
axios.get(this.email_edit_route,this.mailtemplates)
.then((res) => {
this.mailtemplates = res.data.template;
})
axios.post(this.email_edit_route, this.mailtemplates)
.then((res) => {
alert('Mail sent successfull!')
})
route file
Route::get('api/email/create', ['as' => 'email.create', 'uses' => 'Havence\AutoMailController#create']);
Route::get('automail/mail', 'Havence\AutoMailController#mail');
Route::get('automail/index',['as'=>'email.index','uses' => 'Havence\AutoMailController#index']);
Route::post('automail/edit/{id}',['as'=>'email.edit','uses' => 'Havence\AutoMailController#edit']);
Route::get('automail/delete',['as'=>'email.delete','uses' => 'Havence\AutoMailController#destroy']);
I kept searching for this but couldn't find an answer that will make this clear.
Thanks!
As per your error and your route file you are using POST method on your edit page but your edit method accepts only GET method that is why you are getting this error.
I'm getting this error

Fetch data from mysql table with php and react native

I want to display data from the MySQL table that is processed with PHP and react native but does not provide a response and does not display any error messages. If the PHP script I run with my browser will appear as follows:
[
{"group":"1","name":"Soy Souce A"},
{"group":"2","name":"Soy Souce B"},
{"group":"3","name":"Chili Tomato Souce"},
{"group":"4","name":"Vinegar"},
{"group":"5","name":"Syrup"}
]
This is the screen capture display:
My question :
Why the data can not be displayed
As in screen capture, why 3 headers can appear, header 2 is for navigation, how to eliminate headers 1 and 3
please help me overcome it, thank you
This is the react native script
import React, { Component } from 'react';
import DatePicker from 'react-native-datepicker'
import { View, Text, TouchableOpacity, FlatList } from 'react-native';
import { createStackNavigator } from 'react-navigation-stack'
import { createAppContainer } from 'react-navigation'
import Icon from 'react-native-vector-icons/MaterialIcons';
import { Item, } from 'native-base';
class DataSearch extends React.Component {
constructor(props){
super(props)
this.state = {
date:"",
isLoading: false
}
}
componentDidMount() {
var that = this;
var date = new Date().getDate();
var month = new Date().getMonth() + 1;
var year = new Date().getFullYear();
that.setState({
date: date + '-' + month + '-' + year,
});
}
DataShowProcess = () =>{
const { date } = this.state ;
this.setState({
dataSource: [],
isLoading: true
});
fetch('https://example.com/item_group.php', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
dateSearch: date,
})
})
.then((response) => response.json())
.then((responseJson) => {
this.setState({
isLoading: false,
dataSource: responseJson
});
this.props.navigation.navigate('Second', this.state.dataSource);
})
.catch((error) => {
console.error(error);
});
}
render(){
return (
<View>
<DatePicker
style={{width: 200}}
date={this.state.date}
mode="date"
placeholder="select date"
format="DD-MM-YYYY"
confirmBtnText="Confirm"
cancelBtnText="Cancel"
customStyles={{
dateIcon: {
position: 'absolute',
left: 200,
top: 0,
marginLeft: 0
},
dateInput: {
marginLeft: 100
},
}}
onDateChange={(date) => {this.setState({date: date})}}
/>
<TouchableOpacity
style={{ alignItems: 'center'}}
onPress={this.DataShowProcess}
>
<Icon name='search' size={35} color='black'/>
</TouchableOpacity>
</View>
)
}
}
class DataShow extends React.Component {
render(){
const { navigation } = this.props;
return (
<View style={{flex: 1, paddingTop:20}}>
<FlatList
data={this.state.responseJson}
renderItem={({item}) => <Text>{item.group}, {item.name}</Text>}
keyExtractor={({id}, index) => id}
/>
</View>
)};
}
const RootStack = createStackNavigator({
First: DataSearch,
Second: DataShow,
});
export default createAppContainer(RootStack);

select multi image from gallery for send to server with react-native

I try to send multi selected image and upload them to server. I can use react-native-image-picker to select one image and transfer this to base64 and save on state after that send it to the server. but I want multi-select from the gallery and to send them to server . may anyone help me to do that? first, how can I select the multi image and save data of that image to state? second, how can I send that state to save PHP server? third how to show that to the client in the app? in below you can see my cod. thanks
import React, { Component } from 'react';
import { StyleSheet, Text, View, PixelRatio, TouchableOpacity, Image, TextInput, Alert } from 'react-native';
import ImagePicker from 'react-native-image-picker';
import {
handleAndroidBackButton,
removeAndroidBackButtonHandler
} from '../component/androidBackButton';
import RNFetchBlob from 'rn-fetch-blob';
import { ScrollView } from 'react-native-gesture-handler';
class testImage extends Component {
constructor(props) {
super(props);
this.state = {
ImageSource1: null,
ImageSource2: null,
ImageSource3: null,
data: [],
Image_TAG: ''
};
}
componentDidMount() {
handleAndroidBackButton(() => { this.props.navigation.navigate('AuthLoading') });
}
componentWillUnmount() {
removeAndroidBackButtonHandler();
}
selectPhotoTapped(num) {
const options = {
quality: 1.0,
maxWidth: 500,
maxHeight: 500,
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 = { uri: response.uri };
switch (num) {
case '1':
this.setState({
ImageSource1: source,
data: [...this.state.data, response.data],
});
break;
case '2':
this.setState({
ImageSource2: source,
data: [...this.state.data, response.data],
});
break;
case '3':
this.setState({
ImageSource3: source,
data: [...this.state.data, response.data],
});
break;
default:
break;
}
}
});
}
uploadImageToServer2 = () => {
alert(this.state.data)
}
uploadImageToServer = () => {
RNFetchBlob.fetch('POST', 'http://192.168.2.102/Project/upload_image.php', {
Authorization: "Bearer access-token",
otherHeader: "foo",
'Content-Type': 'multipart/form-data',
}, [
{ name: 'image', filename: 'image.png', type: 'image/png', data: this.state.data[0] },
{ name: 'image', filename: 'image.png', type: 'image/png', data: this.state.data[1] },
{ name: 'image', filename: 'image.png', type: 'image/png', data: this.state.data[2] },
{ name: 'image_tag', data: this.state.Image_TAG }
]).then((resp) => {
var tempMSG = resp.data;
tempMSG = tempMSG.replace(/^"|"$/g, '');
Alert.alert(tempMSG);
}).catch((err) => {
// ...
})
}
render() {
return (
<ScrollView>
<View style={styles.container}>
<TouchableOpacity onPress={()=>this.selectPhotoTapped('1')}>
<View style={styles.ImageContainer}>
{this.state.ImageSource1 === null ? <Text>Select a Photo</Text> :
<Image style={styles.ImageContainer} source={this.state.ImageSource1} />
}
</View>
</TouchableOpacity>
<TouchableOpacity onPress={()=>this.selectPhotoTapped('2')}>
<View style={styles.ImageContainer}>
{this.state.ImageSource2 === null ? <Text>Select a Photo</Text> :
<Image style={styles.ImageContainer} source={this.state.ImageSource2} />
}
</View>
</TouchableOpacity>
<TouchableOpacity onPress={()=>this.selectPhotoTapped('3')}>
<View style={styles.ImageContainer}>
{this.state.ImageSource3 === null ? <Text>Select a Photo</Text> :
<Image style={styles.ImageContainer} source={this.state.ImageSource3} />
}
</View>
</TouchableOpacity>
<TouchableOpacity onPress={()=>this.uploadImageToServer2()} activeOpacity={0.6} style={styles.button} >
<Text style={styles.TextStyle}> U2242D IMAGE TO SERVER </Text>
</TouchableOpacity>
<TouchableOpacity onPress={this.uploadImageToServer} activeOpacity={0.6} style={styles.button} >
<Text style={styles.TextStyle}> UPLOAD IMAGE TO SERVER </Text>
</TouchableOpacity>
</View>
</ScrollView>
);
}
}
export default testImage;
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
backgroundColor: '#FFF8E1',
paddingTop: 20
},
ImageContainer: {
borderRadius: 10,
width: 250,
height: 250,
borderColor: '#9B9B9B',
borderWidth: 1 / PixelRatio.get(),
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#CDDC39',
},
TextInputStyle: {
textAlign: 'center',
height: 40,
width: '80%',
borderRadius: 10,
borderWidth: 1,
borderColor: '#028b53',
marginTop: 20
},
button: {
width: '80%',
backgroundColor: '#00BCD4',
borderRadius: 7,
marginTop: 20
},
TextStyle: {
color: '#fff',
textAlign: 'center',
padding: 10
}
});
Please refer here, Multiple image selection is not supported by
react-native-image-picker
for IOS.
I use react-native-image-crop-picker which supports multiple image selection for both android & ios
import ImagePicker from 'react-native-image-crop-picker';//import
ImagePicker.openPicker({
includeBase64: true, // for base 64 string
multiple: true,// To support multiple image selection
quality: 1.0,
maxWidth: 500,
maxHeight: 500,
}).then(image => {
for (i = 0; i < image.length; i++) {
this.state.images.push(image[i].data)//image[i].data=>base64 string
}
}
uploadImageToServer = () => {
this.state.images.map((data, key) => {
RNFetchBlob.fetch('POST', 'http://192.168.2.102/Project/upload_image.php', {
Authorization: "Bearer access-token",
otherHeader: "foo",
'Content-Type': 'multipart/form-data',
},
[{ name: 'image', filename: 'image.png', type: 'image/png', data: data },
{ name: 'image_tag', data: this.state.Image_TAG }]).then((resp) => {
var tempMSG = resp.data;
tempMSG = tempMSG.replace(/^"|"$/g, '');
Alert.alert(tempMSG);
}).catch((err) => {
// ...
})
})
}

How to remove an specific data from database using react native and php

I'm a beginner with react native. In my react native project, I have this front-end.
Here, all these CIS, PST and all other data are retrieved from the database by creating a JSON object in PHP file. They are listed as shown and I have added a delete button for each data of database table as you can see in the photo. But I couldn't add a functionality to the delete button yet because I couldn't specify the data to the button. What I want is, if I click the delete button in front of CIS, delete CIS row only. If I click the delete button in front of PST, delete PST row only. How to specify that data to the button and delete it.
This is my react native code.
import React, { Component } from 'react';
import { AppRegistry, Text, AsyncStorage, StyleSheet, TextInput, View, Alert, Button, FlatList, TouchableOpacity } from 'react-native';
class MainProject extends Component {
constructor(props) {
super(props)
this.state = {
name: ''
};
this.persistData = this.persistData.bind(this);
}
state = {
data: []
};
persistData() {
let name = this.state.name
AsyncStorage.setItem('name', name).done();
this.setState({ name: name, persistedName: name })
}
check() {
AsyncStorage.getItem('name').then((name) => {
this.setState({ name: name, persistedName: name })
})
}
componentWillMount() {
this.check();
//this.fetchData();
}
fetchData = async () => {
const response = await fetch('http:/192.168.182.131/test/select.php');
const json = await response.json();
this.setState({ data: json.results });
};
removeData = async () => {
const response = await fetch('http:/192.168.182.131/test/delete.php');
const json = await response.json();
this.setState({ data: json.results });
};
InsertDataToServer = () => {
const { name } = this.state;
fetch('http:/192.168.182.131/test/submit_user_info.php', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: name
})
}).then((response) => response.json())
.then((responseJson) => {
// Showing response message coming from the server after inserting records.
Alert.alert(responseJson);
}).catch((error) => {
console.error(error);
});
}
render() {
return (
<View style={styles.MainContainer}>
<TextInput
// Adding hint in Text Input using Place holder.
placeholder="Enter Name"
onChangeText={name => this.setState({ name })}
// Making the Under line Transparent.
underlineColorAndroid='transparent'
style={styles.TextInputStyleClass}
/>
<Button title="SUBMIT" onPress={this.InsertDataToServer} color="#2196F3" />
<Button title="VIEW ALL" onPress={this.fetchData} color="green" style={styles.ViewAll} />
<View>
<Text>STATE:</Text>
<Text>Name: {this.state.name}</Text>
</View>
<View style={styles.container}>
<FlatList
data={this.state.data}
keyExtractor={(x, i) => i}
renderItem={({ item }) =>
<View>
<View>
<Text>
{`${item.name}`}
</Text>
</View>
<View>
<TouchableOpacity onPress={this.removeData}>
<Text style={styles.button}>
DELETE
</Text>
</TouchableOpacity>
</View>
</View>
}
/>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
MainContainer: {
justifyContent: 'center',
flex: 1,
margin: 10
},
TextInputStyleClass: {
textAlign: 'center',
marginBottom: 7,
height: 40,
borderWidth: 1,
// Set border Hex Color Code Here.
borderColor: '#FF5722',
},
container: {
marginTop: 15,
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF'
},
ViewAll: {
marginTop: 50
},
button: {
borderColor: 'red',
backgroundColor: 'red',
width: 60,
textAlign: 'center',
borderRadius: 10,
color: 'white'
}
});
AppRegistry.registerComponent('albums', () => MainProject);
This is my PHP code to create the JSON object using database data.
<?php
include 'DBConfig.php';
$con = mysqli_connect($HostName, $HostUser, $HostPass, $DatabaseName);
$query = "SELECT * FROM Department ORDER BY id ASC";
$res = mysqli_query($con,$query) or die("Query Not Executed " . mysqli_error($con));
$data = array();
while($rows = mysqli_fetch_assoc($res)) {
$data[] = $rows;
}
$write = json_encode(array('results' => $data));
echo $write;
mysqli_close($con);
?>
You need to pass an identifier to PHP. I recommend you to use your id for that. This means, you have to send you id to the client, and if you press on delete, you explicitly tell te server to delete this one id.
Your removeData function would have something like that in it:
fetch('http://192.168.182.131/test/delete.php', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
id: id
})
})
This is not the best solution, but it should work. If you have some time, I also recommend you to take a look at CRUD.

React native http post got Json Parse error: Unrecognized token '<'

When I tried to post data from react-native to PHP API, react-native show the error:
Json Parse error: Unrecognized token '<'
I tested PHP API by postman with the header type 'application/json', it works fine, here is the react-native code, can anyone help me on this? Thanks in advance!
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
ActivityIndicatorIOS,
TextInput,
TouchableOpacity,
} from 'react-native';
const REQUEST_URL = 'http://localhost:8000/user';
export default class extends Component {
constructor(props) {
super(props);
}
_submit() {
fetch(REQUEST_URL, {
method: "POST",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
firstname: "Justin", lastname: "Robot"
})
})
.then((response) => response.json())
.then((responseData) => {
console.log(responseData.body);
})
.done();
}
render() {
return (
<View style={styles.container}>
<TouchableOpacity
style={styles.submitButton}
onPress={() => this._submit()}
>
<Text>http post</Text>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
submitButton: {
backgroundColor: 'lightskyblue',
borderRadius: 5,
paddingTop: 5,
paddingBottom: 5,
paddingLeft: 20,
paddingRight: 20,
}
});
We just ran into this in React Native because our server was returning an error response via HTML.
<html>
<head><title>413 Request Entity Too Large</title></head>
<body bgcolor="white">
<center><h1>413 Request Entity Too Large</h1></center>
<hr><center>nginx</center>
</body>
</html>
The fixes could be any of the following:
1) Prevent the error from happening in your server side code.
2) Do better error handling on your server to return JSON errors instead of HTML errors.
3) Write some client side code to detect that HTML was returned and show a more useful error message.

Categories