Pick images in react native and upload it - reactjs

I want to upload an array of images using react-native-image-crop-picker but I can't fix it.
What I've tried:
Fetch (javascript) and also RN-fetch-blob but no luck
At first the catch error was network error
and now the problem is that I'm sending an empty array to the server
here is my code:
export default class Upload extends Component {
constructor() {
super();
this.state = {
token: '',
photos: [],
};
}
_TakePhoto() {
ImagePicker.openPicker({
multiple: true,
}).then((images) => {
images.map((item, index) => {
ImageResizer.createResizedImage(item.path, 1200, 1200, 'JPEG', 100)
.then((response) => {
// console.warn('Resized img is: ', response);
this.state.photos.push(response);
console.warn('Resized img state is: ', this.state.photos);
this._submit_pictures();
})
.catch((err) => {});
});
});
}
_submit_pictures() {
let formData = new FormData();
for (let i = 0; i < this.state.photos.length; i++) {
let file = {
uri: this.state.photos[0].path,
// uri: this.state.photos[0].path.replace('file:///', ''),
// uri: this.state.photos[0].uri,
type: this.state.photos[0].mime,
name: this.state.photos[0].name,
};
formData.append('pics[]', file);
}
// uri: this.state.photos[0].uri.replace("file:///", "file://"),
formData.append('postId', postId);
formData.append('token', token);
console.log('formData value: ', formData);
axios({
url: 'https://rahnama.com/webservice/submitPictures',
method: 'POST',
headers: {
// "Accept": "application/json",
'Content-Type': 'multipart/form-data',
},
// formData
body: formData,
})
.then((response) => {
console.warn('upload res: ', response);
})
.catch((error) => console.warn('upload err: ', error.response.request._response));
}
render() {
return <Text onPress={() => this._TakePhoto()}> Pick </Text>;
}
}

Solved it by sending the image data in base64.
1- Pick the image
2- convert it to base64
3- pass the base64 string as the payload

Related

Send images to backend using ReactJS

I want to make a post request to backend with all form data.
Uploading the images i get an array with data:
const normFile = e => {
const getFileList = e.fileList.map( i => i.originFileObj);
console.log('Upload event:', getFileList);
fetch('https:///uploadapi', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ images: getFileList })
})
.then(async response => {
const data = await response.json();
console.log(data, 'res data')
})
.catch(error => {
console.error('There was an error!', error);
});
if (Array.isArray(e)) {
return e;
}
return e && e.fileList;
};
Above is my code where i use Ant Design uploader.
But how to delete the File text before each object?
You have to use multipart/form-data header
Let's say you have an input
<input type="file" onChange={uploadFile}/>
And logical part:
uploadFile = (e) => {
const formData = new FormData();
formData.append('name_your_file', e.target.files[0])
fetch('https:///uploadapi', {
method: 'POST',
headers: { 'Content-Type': 'multipart/form-data' },
body: formData
})
}

react native upload image with axios

I have this data
came from react-native-image-picker
data: "/9j/4AAQSkZJRgABAQAAAQABAAD//gA7Q1JFQVRPUjogZ2Qtan" => 90kb
fileName: "77677.jpg"
fileSize: 67542
height: 600
isVertical: true
originalRotation: 0
path: "/storage/emulated/0/Download/77677.jpg"
type: "image/jpeg"
uri: "content://media/external/images/media/18584"
width: 399
__proto__: Object
and am try to set this data in object type #FromData to upload #img
var binaryDataInBase64 = new FormData();
binaryDataInBase64.append('file', {
// data: response.data,
uri: 'file://' + response.uri,
name: 'MMM.jpg',
type: response.type
})
console.log('=======================>', binaryDataInBase64)
axios.post(
'https://danskeclouddemo.com/api/file',
{ file: binaryDataInBase64 },
{ headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'multipart/form-data' } }
).then(res => {
console.log(res)
}).catch(error => {
console.log(error)
})
and this is BackEnd Postman Working good Postman collection
//======================
//======================
Edit
Some people talk about the problem from react native version after 0.61.5
in this link issues
Your form data must be like that.
formdata.append('file',{
uri: Platform.OS === 'android' ? photo.uri : 'file://' + photo.uri,
name: 'test',
type: 'image/jpeg' // or your mime type what you want
});
Then
axios.post('/users/profilepic', formdata, config).then((res) => {
console.log(res.data);
return res.data;
});
Rather using, axiom use fetch simple, approach to upload, image
this.setState({imageLoading:true})
const credentials={
userId:this.state.userId
}
try {
let response = await fetch(
'url',
{
'method': 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'multipart/form-data',
},
body: createFormData(source, credentials)
}
);
if (response.status == 200) {
response.json().then(data => {
switch (data.status) {
case 200:
break;
}
});
}else {
this.setState({imageLoading:false ,isLoading:false})
}
} catch (error) {
this.setState({imageLoading:false,isLoading:false})
console.error(error);
}
const createFormData=(image,body)=>{
var data = new FormData();
data.append(image, {
uri: Platform.OS === "android" ? image.uri : image.uri.replace("file://", ""),
name: `dummy${Date.now()}.jpg`,
type: 'image/*'
})
Object.keys(body).forEach(key => {
data.append(key, body[key]);
});
return data
}

react native post form data with object and file in it using axios

so i want to upload
object as data
and file as Note
to api using axios
uploadToServer= () => {
const file =this.state.photo
let data2 ={sale_id:1,
note_type_id:4,
description:"test",
note_content_item:" hi from broker hub"
}
let data = new FormData()
data.append('data[sale_id]', '1')
data.append('data[note_type_id]', '4')
data.append('data[description]', "test")
data.append('data[note_content_item]', "test")
console.log(data)
axios({
url: api',
method: 'POST',
data: data,
headers: {
'Content-Type' : 'multipart/form-data',
'Authorization':'Basic YnJva2VyOmJyb2tlcl8xMjM='
}
})
.then(resp => console.log(resp.data.response))
.catch(error => console.error(error));
}
first i am trying with data without Note i can do it in postman
but with my code i got error
message: "Can not save file"
response_code: 10
i got this error only if i change the key from data to something else
when you are using react-native you don't need "form-data" package. Because react native polyfills standard FormData api and exports it as global.
second problem is axios converts form data automatically to string, so you need to use transformRequest config on request to override it.
import { AxiosRequestConfig } from "axios";
const FormData = global.FormData;
const axiosInstance = axios.create({
baseURL: 'example.com', // use with scheme
timeout: 30000,
headers: {
"X-Platform": 'iOS',
"X-App-Build-Number": '1.0.0',
},
});
const formData = new FormData();
formData.append("userId", "123456");
formData.append("file", {
uri: "/dev/sda/abc.png",
type: "image/png",
name: "abc.png",
});
const config: AxiosRequestConfig = {
method: "post",
url: "/process/start",
responseType: "json",
headers: {
'Content-Type': 'multipart/form-data',
// if backend supports u can use gzip request encoding
// "Content-Encoding": "gzip",
},
transformRequest: (data, headers) => {
// !!! override data to return formData
// since axios converts that to string
return formData;
},
onUploadProgress: (progressEvent) => {
// use upload data, since it's an upload progress
// iOS: {"isTrusted": false, "lengthComputable": true, "loaded": 123, "total": 98902}
},
data: formData,
};
// send post request and get response
const response = await axiosInstance.request(config);
You are not building FormData correctly, Try this:
let data = {sale_id:1,
note_type_id:4,
description:"test",
note_content_item:" hi from broker hub"
}
const formData = new FormData();
formData.append('data', JSON.stringify(data));
formData.append('Note', {
uri: "file://" //Your Image File Path
type: 'image/jpeg',
name: "imagename.jpg",
});
axios({
url : api,
method : 'POST',
data : formData,
headers: {
Accept: 'application/json',
'Content-Type': 'multipart/form-data',
'Authorization':'Basic YnJva2VyOmJyb2tlcl8xMjM='
}
})
.then(function (response) {
console.log("response :", response);
})
.catch(function (error) {
console.log("error from image :");
})
This might help you:
import {Platform} from 'react-native';
import axios from 'axios';
const upload = async readPath => {
console.log('path', readPath);
const URL = 'your-url';
const headers = {
headers: {
'Content-Type': 'multipart/form-data',
Accept: 'application/json',
Authorization: `Bearer ${projectSecret}`,
},
};
const formData = new FormData();
const file = {
uri:
Platform.OS === 'android' ? `file:///${readPath}` : readPath,
type: 'text/plain',
name: name,
};
formData.append('file', file);
await axios
.post(URL, formData, headers, {
timeout: 3000,
})
.then(async response => {
console.log(response.data);
})
.catch(error => {
console.log('error : ', error);
});
};

How to pass POST parameters in fetch for uploading image to server in React Native?

This is the code with I'm trying to send my image to server.
postData = async () => {
var location = await AsyncStorage.getItem('location');
var path = await AsyncStorage.getItem('path');
var post_type = await AsyncStorage.getItem('post_type');
var userId = await AsyncStorage.getItem('userID');
const formData = new FormData();
//I want to pass params in fetch but I don't know how to.
var params = JSON.stringify({
"user": userId,
"description": this.state.description,
"location": location,
"post_type": post_type,
});
const uriPart = path.split('.');
const fileExtension = uriPart[uriPart.length - 1];
formData.append('photo', {
uri: path,
name: `photo.${fileExtension}`,
type: `image/${fileExtension}`,
});
fetch(strings.baseUri+"addPosts",{
method: 'POST',
headers: {
'Content-Type': 'multipart/form-data',
},
body: formData,
})
.then((response) => response.json())
.then((responseJson) => {
alert(responseJson); // This gives me error JSON Parse error: Unexpected EOF
})
.catch((error) => {
console.error(error);
});
}
I want to pass my parameters in fetch. The parameters are params in my case. I want to send these parameters along with my image to server. Please help.
UPDATE
this is when I used alert(JSON.stringify(response));
You can pass parameter with append
reference link: How do I post form data with fetch api?
const formData = new FormData();
formData.append('photo', {
uri: path,
name: `photo.${fileExtension}`,
type: `image/${fileExtension}`,
});
formData.append('user', userId);
formData.append('description', description);
formData.append('location', location);
formData.append('post_type', post_type);
FormData cannot take stringified JSON, but you can iterate over the object, appending values to the form.
Like this:
var params = {
"user": userId,
"description": this.state.description,
"location": location,
"post_type": post_type,
};
const uriPart = path.split('.');
const fileExtension = uriPart[uriPart.length - 1];
formData.append('photo', {
uri: path,
name: `photo.${fileExtension}`,
type: `image/${fileExtension}`,
});
Object.keys(params).forEach(key => formData.append(key, params[key]));
fetch(strings.baseUri+"addPosts",{
method: 'POST',
headers: {
'Content-Type': 'multipart/form-data',
},
body: formData,
})
.then((response) => response.json())
.then((responseJson) => {
alert(responseJson); // This gives me error JSON Parse error: Unexpected EOF
})
.catch((error) => {
console.error(error);
});
}

undefined error when trying to set state

I'm trying to upload images and then set the state for each image uploaded.
However, I keep on getting this error when hitting the 'Upload' button:
catch: TypeError: Cannot read property 'setState' of undefined
The error is occurring in this block of code:
.then(function (response) {
//handle success
console.log('then: ', response);
this.setState({
file: e.target.files[0]
});
})
Any help would be appreciated!
Thanks!
Here is the entire component:
import React, { Component } from 'react';
import axios from 'axios';
class ImageUpload extends Component {
constructor(props) {
super(props);
this.state = { file: '', imagePreviewUrl: '' };
}
_handleSubmit(e) {
e.preventDefault();
let fd = new FormData();
fd.append('image', this.state.file);
const config = {
headers: { 'content-type': 'multipart/form-data' }
}
const postData = {
method: 'POST',
credentials: 'include',
body: fd
}
axios({
method: 'post',
url: `/api/gaming/profiles/${this.props.profileId}/files/upload`,
data: postData
})
.then(function (response) {
//handle success
console.log('then: ', response);
this.setState({
file: event.target.files[0]
});
})
.catch(function (response) {
//handle error
console.log('catch: ', response);
});
}
_handleImageChange(e) {
e.preventDefault();
let reader = new FileReader();
let file = e.target.files[0];
reader.onloadend = () => {
this.setState({
file: file,
imagePreviewUrl: reader.result
});
}
reader.readAsDataURL(file)
}
render() {
const { questionId } = this.props;
let { imagePreviewUrl } = this.state;
let $imagePreview = null;
if (imagePreviewUrl) {
$imagePreview = (<img src={imagePreviewUrl} />);
} else {
$imagePreview = (<div className="previewText">Please select an Image for Preview</div>);
}
console.log('ImageUpload Render()');
return (
<div className="previewComponent">
<input className="fileInput"
type="file"
onChange={(e) => this._handleImageChange(e)} />
<button className="submitButton"
type="submit"
onClick={(e) => this._handleSubmit(e)}>Upload Image</button>
<div className="imgPreview">
{$imagePreview}
</div>
</div>
);
}
}
export default ImageUpload;
Change your Promise resolver to an arrow function, it'll lexically scope this for you.
Change it to:
.then((response) => {
//handle success
console.log('then: ', response);
this.setState({
file: e.target.files[0]
});
})
In your _handleSubmit(e) define var self = this
then use self.setState instead of this.setState
_handleSubmit(e) {
e.preventDefault();
let fd = new FormData();
fd.append('image', this.state.file);
const config = {
headers: { 'content-type': 'multipart/form-data' }
}
const postData = {
method: 'POST',
credentials: 'include',
body: fd
}
var self = this
axios({
method: 'post',
url: `/api/gaming/profiles/${this.props.profileId}/files/upload`,
data: postData
})
.then(function (response) {
//handle success
console.log('then: ', response);
self.setState({
file: event.target.files[0]
});
})
.catch(function (response) {
//handle error
console.log('catch: ', response);
});
}

Resources