How to upload image with react native? - javascript

I upload image with react js like this :
const onSubmit = (e) => {
console.log(e.img);
form.append("file", e.img.originFileObj);
Axios.post("url", form, {
headers: {
Authorization: `bearer ${localStorage.getItem("token")}`,
},
})
};
and the console log for the e.img is :
Now in react native I use the package react-native-image-crop-picker .
and after I set the image file it gives out an object like this :
{"cropRect": {"height": 960, "width": 960, "x": 0, "y": 160}, "height": 400, "mime": "image/jpeg", "modificationDate": "1636923018000", "path": "file:///storage/emulated/0/Android/data/com.myapp/files/Pictures/33fc6a3f-3673-4756-8343-6f6bcb3c1a7b.jpg", "size": 89454, "width": 400}
Now When I try to upload the image it gives error about the img file.
And the backend is node js and I handle image files with multer like this :
const multer = require('multer');
const uuid = require('uuid');
const MIME_TYPE_MAP = {
'image/png': 'png',
'image/jpeg': 'jpeg',
'image/jpg': 'jpg'
};
const fileUpload = multer({
limits: 20000000000,
storage: multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'upload/img');
},
filename: (req, file, cb) => {
const ext = MIME_TYPE_MAP[file.mimetype];
cb(null, uuid.v4() + '.' + ext);
}
}),
fileFilter: (req, file, cb) => {
const isValid = !!MIME_TYPE_MAP[file.mimetype];
let error = isValid ? null : new Error('Invalid mime type!');
cb(error, isValid);
}
});
module.exports = fileUpload;
How can I post the image file in react native like I do in react js ?

Solution 1
Like reactjs, here you can use FormData and append file in that like this:
asycn function uploadImage() {
const formData = new FormData();
const imageData = {
uri: cropImageData.path, // file uri/path
name: 'MyImage.jpg', //file name
type: cropImageData.mime, //file type
}
formData.append("file", imageData);
await fetch(url, {
method: "POST",
headers: {
'Content-Type': 'multipart/form-data',
Authorization: token,
},
data: formData,
}).then((response), {
console.log(response)
}).catch((error) => console.log(response));
}
Solution 2
or you can send base64 string from data, (you can get base64 from crop-image picker)
asycn function uploadImage() {
await fetch(url, {
method: "POST",
headers: {
'Content-Type': 'application/json',
Authorization: token,
},
data: JSON.stringify({
file: imageBase64String,
}),
}).then((response), {
console.log(response)
}).catch((error) => console.log(response));
}
here instead of fetch you can use axios too.

I solved the issue this way
ImagePicker.openPicker({
width: 400,
height: 400,
cropping: true,
includeBase64: true,
})
.then(image => {
setImg(image);
})
.then(() => setModalVisible(prev => !prev));
const nn = JSON.stringify(img.path).substring(
JSON.stringify(img.path).lastIndexOf('/') + 1,
);
const image = {
name: nn,
uri: img.path,
type: img.mime,
size: img.size,
lastModifiedDate: JSON.parse(img.modificationDate),
uid: img.modificationDate,
};
const form = new FormData();
form.append('file', image);
axios
.post('url', form, {
headers: {
Authorization: `bearer ${JSON.parse(token)}`,
},
})

Related

How to make a resumable upload for attachments through Gmail API in react native?

Please do not share the documentation link, it's not straight forward and also the uploading using RNFS and document-picker is a bit confusing..
Code:
const uploadAttachments = async (data, sessionURI, message, onProgress) => {
const {files} = message;
let length = 0;
const formatedFileData = files.map(item => {
length += item.size;
return {
name: item.filename,
filename: item.filename,
filepath: RNFS.DocumentDirectoryPath + '/' + item.filename,
filetype: item.filetype,
};
});
RNFS.uploadFiles({
toUrl: sessionURI,
files: formatedFileData,
method: 'PUT',
headers: {
Authorization: 'Bearer ' + (await getUserToken()),
'Content-Length': length.toString(),
'Content-Type': 'application/json; charset=UTF-8',
},
fields: data,
progress: onProgress,
})
.promise.then(response => {
console.log(response);
})
.catch(error => {
console.log(error);
});
};
const requestSession = async (data: any, postUrl: string) => {
try {
const result = await axios({
data: data,
headers: {
Authorization: 'Bearer ' + (await getUserToken()),
'Content-Type': 'application/json; charset=UTF-8',
'Content-Length': 0,
'X-Upload-Content-Type': 'message/rfc822',
},
method: 'post',
url: postUrl,
});
return result;
} catch (error) {
throw error;
}
};
export const resumeableUpload = async (message, onProgress) => {
try {
const data = await getMetaData(message);
const response = await requestSession(data, RESUMABLE_URL);
const sessionURI = response.headers.location;
const res = await uploadAttachments(data, sessionURI, message, onProgress);
return res;
} catch (error) {
console.log(error);
}
};
I get the error from RNFS saying the 'Socket is closed'!
May be the way i'm uploading the file itself is wrong or is there any other way to upload files to the session uri?
If I send base64encoded bytes of the file, it raw feild becomes too huge for files over 5MB (25mb files) and the app crashes

Getting Formdata empty even after appending values

I have been trying to send an image via native http POST request in my IONIC 4 app. I am getting the selected image and blob but when I am trying to append the same to my formData, my formData is always empty.
Here is my ts code
takePicture(sourceType: PictureSourceType) {
var options: CameraOptions = {
quality: 100,
sourceType: sourceType,
saveToPhotoAlbum: false,
correctOrientation: true
};
this.camera.getPicture(options).then(imagePath => {
if (this.platform.is('android') && sourceType === this.camera.PictureSourceType.PHOTOLIBRARY) {
this.file.resolveLocalFilesystemUrl(imagePath).then((entry: FileEntry) => {
entry.file(file => {
console.log(file);
this.readFile(file);
});
});
}
});
}
readFile(file: any) {
const reader = new FileReader();
reader.onloadend = () => {
const imgBlob = new Blob([reader.result], {
type: file.type
});
const formData = new FormData();
formData.append('file', imgBlob, file.name);
console.log(formData)
console.log(imgBlob)
this.uploadImageData(formData)
};
reader.readAsArrayBuffer(file);
}
async uploadImageData(formData) {
let feedbackData = {
attachment: formData,
feedback: 'test text'
}
this.http.post('http://abctest.rapidesk.in/api/feedback/', feedbackData, { 'Content-Type': 'multipart/form-data', 'Authorization': "Token" + " " + this.authToken })
.then(data => {
console.log(data);
}).catch(err => {
console.log(err)
})
}
I have shared the image of my console.
First console shows my image location and data
Second console is my formData
Third console is my imgBlob
You don't need to bind the image data to FormData. Please follow my code. This works fine with me. It may help you.
getFileFromCamera() {
this.translate.get(["FILE_ADDED_SUCCESSFULLY", "UNABLE_TO_TAKE_PHOTO"]).subscribe(
(values) => {
this.camera.getPicture({
destinationType: this.camera.DestinationType.DATA_URL,
targetWidth: 500,
targetHeight: 500,
quality: 100,
encodingType: this.camera.EncodingType.JPEG,
mediaType: this.camera.MediaType.PICTURE,
correctOrientation: true
}).then((data) => {
const imageData = 'data:image/jpg;base64,' + data;
this.AddDocumentForm.patchValue({'form_file': imageData}); // I am using reactive form group but you can directly add to the API body.
}, (err) => {
console.log(err);
this.csp.showToastMessage(2, values.UNABLE_TO_TAKE_PHOTO);
})
});
}
saveImage() {
this.api.post(endPoint, {image : this.AddDocumentForm.value.form_file).subscribe(()=>{
console.log(res);
});
}
// API service
post(endpoint: string, body: any, reqOpts?: any) {
return this.http.post(this.url + '?' + endpoint, body, reqOpts);
}

How to upload files sent with FormData through Axios ? (TypeError: file.mv is not a function)

So i am sending a file from one server to another using Axios, one is an app backend and the other is a blockchain server.
Where i am sending the file :
router.post("/acme/:id", auth, async (req, res) => {
var formData = new FormData();
console.log(req.files.file)
formData.append("image", req.files.file.data);
var Response;
try {
Response = await axios.post(BC_SERVER + "acmeDataFileUpload", {
id: req.params.id,
data: formData,
headers: {
'Content-Type': 'multipart/form-data'
}
});
} catch (error) {
console.log("Error BlockChain");
}
try {
res.status(201).send("ok");
} catch (e) {
res.status(500).send(e);
}
});
Where Axios is sending it :
app.post('/acmeDataFileUpload', async (req, res) => {
const id_owner = req.body.id;
console.log(req.body)
const file = req.body.data;
const fileName = id_owner;
const filePath = 'files/' + fileName;
console.log(fileName);
file.mv(filePath, async (err) => {
try {
const fileHash = await addFile(fileName, filePath);
fs.unlink(filePath, (err) => {
if (err) console.log(err);
});
const json = '{"dataType": "Object" , "local": "'+localServer+fileHash+'",' +'"ipfsServer": "'+ipfsServer+fileHash+'"}';
console.log(json);
const obj = JSON.parse(json);
res.status(201).send(obj);
} catch (err) {
console.log('Error : failed to download file');
console.log(err);
return res.status(500).send(err);
}
});
});
and this is what the log of req.body is like :
{
id: '5ec2b7d47ae93a49ecb773f6',
data: {
_overheadLength: 144,
_valueLength: 579564,
_valuesToMeasure: [],
writable: false,
readable: true,
dataSize: 0,
maxDataSize: 2097152,
pauseStreams: true,
_released: false,
_streams: [
'----------------------------383350625990492694059785\r\n' +
'Content-Disposition: form-data; name="image"\r\n' +
'Content-Type: application/octet-stream\r\n' +
'\r\n',
[Object],
null
],
_currentStream: null,
_insideLoop: false,
_pendingNext: false,
_boundary: '--------------------------383350625990492694059785'
},
headers: { 'Content-Type': 'multipart/form-data' }
}
Basically i am sending the buffer here, since FormData doesn't accept a file and tells me source.on is not a function i would rather my image is send to req.files instead of req.body, Axios is really confusing me.
headers: formData.getHeaders()

How to send POST request with files in react-native android

I'm trying to send a file with rect-native 62.2 code with fetch request
when i select the file my fill array is this ->
{"data": ~blob image data~,"fileName": "Screenshot_20200504_082033.jpg", "fileSize": 347275, "height": 1544, "isVertical": true, "originalRotation": 0, "path": "/storage/emulated/0/DCIM/Screenshots/Screenshot_20200504_082033.jpg", "timestamp": "2020-05-04T02:50:33Z", "type": "image/jpeg", "uri": "content://media/external/images/media/126441", "width": 720}
i'm using the library for selecting the data is react-native-image-picker
the fetch request i'm sending is will look like this
var picForm = new FormData();
picForm.append('userId', userId);
picForm.append('file', source) // <- this is the main data
fetch(API_HOST + 'user/profilePictureUpload', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'multipart/form-data',
Authorization: 'Basic jfjsfhsjkfhsjkjksksjjksfjkskfksdd',
Authorizationkeyfortoken:''fjsfsfjsfsjhfsjkfhjksfjksfjsf,
},
body: picForm,
}).then(res => res.text()).then(text => console.log(text)).catch(e => console.log(e));
for this code i'm getting an error source is [TypeError: Network request failed]
when i try this
var picForm = new FormData();
picForm.append('userId', userId);
picForm.append('file', {
uri: source.uri, //<- content://media/external/images/media/126441
type: 'image/jpeg',
name: source.fileName //<- Screenshot_20200504_082033.jpg
})
for this code i'm getting an error source is [TypeError: Network request failed]
var picForm = new FormData();
picForm.append('userId', userId);
picForm.append('file', source.files[0]) // <- this is the main data
the error appear is undefined object
var picForm = new FormData();
picForm.append('userId', userId);
picForm.append('file', 'files') // <- this is the main data
the network is correct but this is not i want to send this is the simple string do you guys any idea how to send the file with fetch request
please create image object like this way
var imageData = {
uri: iamge_path,
type: file_type, //the mime type of the file
name: file_name
}
const data = new FormData();
data.append("image",imageData)
Please make sure the request type is post, and your backend is handling the formdata correctly
This code working fine for me for multiple images upload , with photo description and user_id along with progress status
constructor() {
super();
this.state = {
uploadPercentage: 0,
}
}
// upload Files upload_Files = async () => {
upload_File() {
if (this.validate_Fields()) {
const { image, images, files, description, userId, size } = this.state;
console.log('AddPost Screen : upload_File:', 'userId:', userId, 'Files:', files, 'description:', description)
// this.setState({ error: '', loading: true });
if (this.state.type === 'image/jpeg') {
console.log('AddPost Screen : upload_ files :', files);
const formData = new FormData();
formData.append('user_id', userId);
formData.append('description', description);
// formData.append('files[]', files);
for (let i = 0; i < files.length; i++) {
formData.append('files[]', {
name: files[i].path.split('/').pop(),
type: files[i].mime,
uri: Platform.OS === 'android' ? files[i].path : files[i].path.replace('file://', ''),
});
}
// upload percentage progress bar ******************************************************
const options = {
onUploadProgress: (progressEvent) => {
const { loaded, total } = progressEvent;
let percent = Math.floor((loaded * 100) / total)
console.log(`${loaded}kb of ${total}kb | ${percent}%`);
if (percent < 100) {
this.setState({ uploadPercentage: percent })
}
}
}
axios.post(API_URL + '/fileuploadapi/uploadPost', formData, options, {
headers: { "Content-type": "multipart/form-data" }
}).then((response) => {
console.log(JSON.parse(JSON.stringify(response.status)));
// upload percentage progress
this.setState({ uploadPercentage: 100 }, () => {
setTimeout(() => {
this.setState({ uploadPercentage: 0 })
}, 1000);
})
this.cleanupImages();
Alert.alert('Upload Post Successfully');
}).catch((error) => {
console.log(error);
this.cleanupImages();
Alert.alert('image Upload Post Failed , Try again !');
});
}
}
}
// clear files data
cleanupImages() {
this.setState({
description: '',
image: null,
images: null,
// video: '',
files: '',
uploadPercentage: 0,
})
ImagePicker.clean().then(() => {
console.log('removed tmp images from tmp directory');
}).catch(error => {
alert(error);
});
}
If anything need let me know

Unable to convert file to binary format for sending to wit.ai api using node.js

I am facing an issue in converting Audio file to Binary format. I need to send it to Wit.AI api which is expecting the data in that format. I am using node.js. In my front-end I am recording the user voice using Mic-recorder Module. Any suggestions are welcome.
My front end code:
var recorder;
function startRecording() {
recorder = new MicRecorder({
bitRate: 128
});
recorder.start()
}
function stopRecording() {
recorder.stop().getMp3().then(([buffer, blob]) => {
console.log(buffer, blob);
const file = new File(buffer, 'music.mp3', {
type: blob.type,
lastModified: Date.now()
})
console.log(file)
axios({
method: 'post',
url: `${appUrl}/open_api/voice/send?data=${buffer}`
}).then(function (res) {
console.log(res)
if (res.data.success) {
console.log('done',res)
} else {
console.log(res.data)
}
})
})
};
After recording Successfully, I want to send the file to my api in order to call wit.ai /speech api.
My back end code is:
router.post('/voice/send', //chatbot response api
async (req, res, next) => {
let thread_id = '99-99-99-99'
let audioBinary = req.query.data
console.log(audioBinary)
let appId = "5d07621d6b79be66a73f4005"
let sessionId ="10-10-10-10"
let accessToken = await db.model('ChatBotApp').findOne({
_id: req.query.key
}, {
access_token: 1
}).lean()
var options = {
method: 'POST',
uri: 'https://api.wit.ai/speech?v=20190513',
body : audioBinary,
encoding: null,
headers: {
'Authorization': 'Bearer ' + "HY3ZWSUGPBPD5LWZLRSZ3QJCDC27M6EW",
'Content-Type': 'audio/mpeg',
},
// json: true // Automatically stringifies the body to JSON
};
rp(options)
.then(async function (parsedBody) {
console.log('this called',parsedBody)
return
// let response = await firstEntityValue(parsedBody, appId, message, thread_id)
// events.emit('Chats', appId, thread_id, message, sessionId, response);
return res.apiOk(response)
})
.catch(function (err) {
console.log(err)
return res.apiError('Issue while creating app!', err);
})
}
)
var recorder
function startRecording() {
recorder = new MicRecorder({
bitRate: 128
});
recorder.start()
}
function stopRecording() {
recorder.stop().getMp3().then(([buffer, blob]) => {
console.log(buffer, blob);
const file = new File(buffer, 'music.mp3', {
type: blob.type,
lastModified: Date.now()
})
var bodyFormData = new FormData();
bodyFormData.append('file', file);
console.log(file)
axios({
method: 'post',
url: `${appUrl}/open_api/voice/send`,
headers: {
'Content-Type': 'multipart/form-data'
},
data: bodyFormData
}).then(function (res) {
console.log(res)
if (res.data.success) {
console.log('done', res)
} else {
console.log(res.data)
}
})
})
};
API
router.post('/voice/send',upload.single('file'), //chatbot response api
async (req, res, next) => {
console.log(req.file)
let thread_id = '99-99-99-99'
let audioBinary = req.file.buffer
let appId = "5d07621d6b79be66a73f4005"
let sessionId = "10-10-10-10"
let accessToken = await db.model('ChatBotApp').findOne({
_id: req.query.key
}, {
access_token: 1
}).lean()
var options = {
method: 'POST',
uri: 'https://api.wit.ai/speech?v=20190513',
headers: {
'Authorization': 'Bearer ' + "HY3ZWSUGPBPD5LWZLRSZ3QJCDC27M6EW",
'Content-Type': 'audio/mpeg',
},
body: audioBinary
// json: true // Automatically stringifies the body to JSON
};
rp(options)
.then(async function (parsedBody) {
console.log('this called', parsedBody)
return
// let response = await firstEntityValue(parsedBody, appId, message, thread_id)
// events.emit('Chats', appId, thread_id, message, sessionId, response);
return res.apiOk(response)
})
.catch(function (err) {
console.log(err)
return res.apiError('Issue while creating app!', err);
})
})

Categories