Media Captured Video as Form Data - ionic4

I need to send my captured video to Backend as Form Data. Please help.
this.mediaCapture.captureVideo({ limit: 1, duration: 210 }).then(
(data: MediaFile[]) => {
if (data.length > 0) {
console.log(data[0])
}
},
(err: CaptureError) => console.error(err)
);

Related

React-Native 62.2 code image upload Error : network error

I am using React-Native two days back After React-Native version upgrading to 0-62.2, I encountered many problems.
Among them important one is image upload error getting [Error:Network error ]
Before upgrading the React-native my code is working fine
Below code is working fine for me for multiple image upload before upgrading to React-Native 0.62.2 but now i am getting [Error: Network error]
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 anyone know the solution please let me know ...
I just found the solution for the React-Native 62.2 upgrading error for image upload Error
[Error: network error]
Just remove the file "ReactNativeFlipper.java" from debug/java folder
File Location :
android/app/src/debug/java/com/appname/ReactNativeFlipper.java

Convert Image to base64 in react native

I have used react-native-image-picker and now I select image from the Photo library. To send the that image to API I have to convert it first into base64 and then into byte array. I have the filepath in response.uri. How do I do it?
When I did console.log(response) I am getting this in result
'Response = ', {
fileSize: 6581432,
longitude: -17.548928333333333,
uri: 'file:///Users/shubhamb/Library/Developer/CoreSimulator/Devices/B58314DF-F0A9-48D2-B68A-984A02271B72/data/Containers/Data/Application/63143214-8A03-4AC8-A79C-42EC9B82E841/tmp/2AACBC57-0C07-4C98-985E-154668E6A384.jpg',
fileName: 'IMG_0003.JPG',
latitude: 65.682895,
origURL: 'assets-library://asset/asset.JPG?id=9F983DBA-EC35-42B8-8773-B597CF782EDD&ext=JPG',
type: 'image/jpeg',
height: 2002,
width: 3000,
timestamp: '2012-08-08T18:52:11Z',
isVertical: false,
}
Since you're using react-native-image-picker, it already returns the Base64 value in its response
ImagePicker.showImagePicker(options, (response) => {
const base64Value = response.data;
});
Documentation for the response
I suddenly ran into this issue while updating my app. What I found is that previous react-native-image-picker used to provide base64 as response.data. But now there is an includeBase64 in the options object so that you can control whether you need the base64 data or not. So my code became something like the following
captureTradeLicenseImage() {
let options = {
maxHeight: 250,
maxWidth: 350,
includeBase64: true //add this in the option to include base64 value in the response
}
ImagePicker.launchCamera(options, (response) => {
console.log('Response = ', response)
if (response.didCancel) {
console.log('User cancelled image picker')
}
else if (response.error) {
console.log('ImagePicker Error: ', response.error)
}
else if (response.customButton) {
console.log('User tapped custom button: ', response.customButton)
}
else if (response.fileSize > 5242880) {
Alert.alert(
"Nilamhut Say\'s",
"Oops! the photos are too big. Max photo size is 4MB per photo. Please reduce the resolution or file size and retry",
[
{ text: "OK", onPress: () => console.log('ok Pressed') }
],
{ cancelable: false }
)
}
else {
this.setState({tradeLicenseImageData: response.base64}) //access like this
}
})
}
The standalone expo FileSystem package makes this simple:
const base64 = await FileSystem.readAsStringAsync(photo.uri, { encoding: 'base64' });
https://docs.expo.io/versions/latest/sdk/filesystem/
https://github.com/expo/expo/tree/master/packages/expo-file-system
As 2019-09-27 this package handles both file:// and content:// uri's
I'm too late but if I can help others that is looking how to get the base64 data from an image:
In the options object you have to set the base64 option to true, like this:
const options = {
title: 'Choose an Image',
base64: true
};
ImagePicker.launchImageLibrary(options, response => {
console.log(response.data);
});
As simple as that:
import { CameraOptions, ImagePickerResponse, launchCamera } from 'react-native-image-picker';
Wrap in your component:
const [b64, setB64] = useState<string>("");
const manageImage = async (response: ImagePickerResponse) => {
if (response.didCancel) {
return;
} else if (response.assets) {
if (response.assets?.length > 0) {
setB64(response.assets[0].base64 ? response.assets[0].base64 : "");
}
}
}
launchCamera(options, (response) => {
manageImage(response);
});

Cannot return position in from navigation.geolocation.getCurrentPosition() in react-native

I am trying to get the geolocation after an image has been taken in react-native. A user captures an image and the image along with the geolocation is stored in an object and sent via a http request to the server.
The function to save get the geolocation works fine bur I am unable to return the geolocation to be stored in the object for http transfer. I get an undefined.
console.log('getCoordinates run')
await navigator.geolocation.getCurrentPosition(
position => {
let coordinates = `${position.coords.longitude},
${position.coords.latitude}`
return coordinates
},
error => Alert.alert(error.message),
{ enableHighAccuracy: false, timeout: 20000, maximumAge: 1000 }
)
}
captureImage = async () => {
if (this.camera) {
const options = { quality: 0.5, base64: true };
const data = await this.camera.takePictureAsync(options);
console.log(data);
let postData = {
user: 1,
coordinates: this.getCoordinates(),
image: `data:image/jpeg;base64${data.base64}`,
}
console.log(postData)
axios.post('https://localhost:5000/api/posts', postData)
.then(post => res.json(post))
.catch(err => console.log(err))
}
}
Expected results is that when the captureImage function runs the getCoordinates function withing the postData object returns the current geolocation before that data is transferred to the server.
How geolocation.getCurrentPosition function works here is that it sets a callback to send data once it acquire user's location. It takes time to acquire and send relevant data. That's why we use callbacks or promises. But in your code, you just call the function and without waiting for its response, just do the API call.
I assume you have used Async function to do this. But if I were you, I'd try to use Promises here to resolve this issue. Simple example would be,
captureImage = async () => {
if (this.camera) {
// ... do your camera tasks
}
this.sendImageData(data); // data is what you got from camera.
}
getGeoInfo = () => {
return new Promise((resolve, reject) => {
navigator.geolocation.getCurrentPosition(
position => {
let coordinates = `${position.coords.longitude},
${position.coords.latitude}`
resolve(coordinates);
},
error => reject(error),
{ enableHighAccuracy: false, timeout: 20000, maximumAge: 1000 }
)
})
}
sendImageData = (cameraData) => {
let coordinates = '';
getGeoInfo.then(crdnts => coordinates = crdnts );
// now coordinates have all relevant data you wished.
const data = { //... make the object as you want }
// do the API call using axios as you've already done.
}

How do I improve my image download speed?

I am using react-native-fetch-blob for download image.
Here's my source code.
downloadThumb(element) {
return new Promise((resolve, reject) => {
RNFetchBlob.config({
// add this option that makes response data to be stored as a file,
// this is much more performant.
fileCache: true,
path: `${DocumentDirectoryPath}/thumbs/${element}`,
})
.fetch(
'GET',
`https://www.searchforsites.co.uk/images/thumbs/${element}`,
{
// some headers ..
},
)
.then((res) => {
resolve(true);
})
.catch((err) => {
// console.log('Error: ', err);
// this.setState({ modalOpen: false, regionUpdated: true });
// this.findUser();
reject(true);
});
});
}
///////////////////////////////////////
recursive_thumb(element) {
this.downloadThumb(element).then((response) => {
if (this.state.count > this.state.total_thumbs) {
this.setState({ modalOpen: false });
setThumbDownloaded();
return true;
}
this.state.count += 1;
// console.log(this.state.count);
this.setState({ totalCount: this.state.total_thumbs, fetchedCount: this.state.count });
this.recursive_thumb(this.state.thumbs[this.state.count]);
});
}
filesize is around 8KB. Now I am donwloading one by one.
And downloading one image(8KB) takes a second.
Is there any solution to improve downloading speed?
Thanks for your time.
If you'd like to increase the download of a sequence of images:
Just create a Promise.all, which will fetch them all parallel
Promise.all([
downloadThumb('data.jpeg'),
downloadThumb('users.jpeg'),
downloadThumb('products.jpeg')
])
.then(function(data) {
console.log('Parallel promises >>>', data);
});
Check out this github page: https://github.com/jaydson/es7-async

React Native how to upload multiple photos to server at once

I've tried to upload multiple images to server at a once by using fetch.
Here is my code chip.
chooseImage(){
ImagePicker.openPicker({
multiple: true,
waitAnimationEnd: false
}).then(images => {
var photos = []
images.map((image, i) => {
photos.push({
uri:image.path,
name: image.name,
type: 'image/jpg'
})
let source = {uri: image.path}
this.state.photos.push({image: source, check: true, hairstyle: '', price: ''})
})
var data = new FormData();
data.append('photos', photos)
const config = {
method: 'POST',
headers: {
'Accept':'application/json',
'Content-Type':'multipart/form-data;',
'Authorization': this.props.auth.token
},
body: data,
}
fetch("http://**.***.***.***/api/providers/uploadPhotos", config)
.then(res=>res.json()).then((res) => {
console.log("----------Response----------")
console.log(res)
this._getStylist()
this.setState({photo_take: false});
}).catch(err=>{
console.log("------------Error-----------")
console.log(err)
console.log("error in uploading image")
}).done()
}).catch(e => {
console.log(e);
});
}
When I try it, I get 200 response from server and photos doesn't upload to server actually.
I searched the solution a few days, but couldn't find the suitable solution.
Thanks for any suggestion.
I am new at react native but seems like you can loop throght images array to upload images Maybe you can add this post actions in promise array then you can be sure that every photo added to your storage. I use promise array methods while working on my node js server project its very useful.
Edit for example:
var photos=[];
var promise_array=[];
photos.forEach(function(photo){
const config = {
method: 'POST',
headers: {
'Accept':'application/json',
'Content-Type':'multipart/form-data;',
'Authorization': this.props.auth.token
},
body: photo,
}
promise_array.push(fetch("http://**.***.***.***/api/providers/uploadPhotos", config)
.then(res=>res.json()).then((res) => {
console.log("----------Response----------")
console.log(res)
this._getStylist()
this.setState({photo_take: false});
}).catch(err=>{
console.log("------------Error-----------")
console.log(err)
console.log("error in uploading image")
}).done())
})
Promise.all(promise_array);
Since fetch is a promise I can put in promise array. Maybe there is syntax error in example and I am not sure react native support promise methods fully but here is documentation for promise method I use https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise/all