I am working on my Ionic 4 app and I have used the camera plugin for image uploading and I have converted the image to the base64 for showing the image but the problem is that I am not able to convert the base64 to proper image path for sending it to the API.
This is my editimage.page.html:
<ion-item class="newitem2">
<ion-avatar class="image-center">
<img name="profile_pic" [src]="this.userdetailsedit.value.profile_pic"/>
<ion-icon (click)="presentActionSheet()" class="myicon11" name="create"></ion-icon>
</ion-avatar>
</ion-item>
This is my editprofile.page.ts:
async UpdateUserDetails(){
this.storage.get('USER').then(userde => {
if (userde) {
this.userdetails = userde;
const userdetailseditss = {
first_name: this.userdetailsedit.value.first_name,
last_name: this.userdetailsedit.value.last_name,
mobile: this.userdetailsedit.value.mobile,
profile_pic: this.userdetailsedit.value.profile_pic,
};
this.chakapi.UserProfileUpdate(userdetailseditss, 'userUpdateProfile/' + this.userdetails.id).subscribe((data) => {
console.log(data);
}, error => {
console.log(error); });
}
});
}
async imageuserchoose(sourceType){
const options: CameraOptions = {
quality: 76,
sourceType: sourceType,
destinationType: this.camera.DestinationType.FILE_URI,
encodingType: this.camera.EncodingType.JPEG,
mediaType: this.camera.MediaType.PICTURE,
saveToPhotoAlbum: true,
correctOrientation: true,
}
this.camera.getPicture(options).then((imageData) => {
if (sourceType === this.camera.PictureSourceType.PHOTOLIBRARY) {
let path = imageData.substring(0, imageData.lastIndexOf('/') + 1);
let filename = imageData.substring(imageData.lastIndexOf('/') + 1);
let index = filename.indexOf('?');
if (index > -1) {
filename = filename.substring(0,index);
}
this.file.readAsDataURL(path, filename).then(data => {
this.imagepic = data;
this.userdetailsedit.patchValue({
profile_pic: data,
});
});
}
if (sourceType === this.camera.PictureSourceType.CAMERA) {
let filename = imageData.substring(imageData.lastIndexOf('/') + 1);
let path = imageData.substring(0, imageData.lastIndexOf('/') + 1);
this.file.readAsDataURL(path, filename).then(data => {
this.imagepic = data;
this.userdetailsedit.patchValue({
profile_pic: data,
});
});
}
}, (err) => {
});
}
async presentActionSheet() {
const actionSheet = await this.actionSheetController.create({
header: 'Select Image Source',
backdropDismiss:true,
buttons: [{
text: 'Choose From Gallery',
icon: 'images',
cssClass: 'myActionSheetBtnStyle',
handler: () => {
this.imageuserchoose(this.camera.PictureSourceType.PHOTOLIBRARY);
}
},
{
text: 'Use Camera',
icon: 'camera',
cssClass: 'myActionSheetBtnStyle',
handler: () => {
this.imageuserchoose(this.camera.PictureSourceType.CAMERA);
}
}]
});
await actionSheet.present();
}
}
The problem is that when I am sending the image to the API, it is base64 and I am not able to convert it before sending.
Any help is much appreciated.
Please try this. You can use file transfer Native Plugin for this. It will solve your problem.
In the ts file:
async UpdateUserDetails(){
if(this.imagepic && this.fileUploadName) {
let fileTransfer = this.transfer.create();
let options: FileUploadOptions = {
fileKey: 'profile_pic',
fileName: this.fileUploadName,
headers: {}
}
options.params = {
first_name: this.userdetailsedit.value.first_name,
last_name: this.userdetailsedit.value.last_name,
mobile: this.userdetailsedit.value.mobile,
old_password: this.userdetailsedit.value.old_password,
password: this.userdetailsedit.value.password,
};
this.storage.get('USER').then(userde => {
if (userde) {
this.userdetails = userde;
fileTransfer.upload(this.imagepic, this.apiUrl+'userUpdateProfile/'+this.userdetails.id, options)
.then((data) => {
if(data && data.responseCode==200){
let response=JSON.parse(data.response);
if(response.status === "success"){
this.storage.set('ID', response.data.id);
this.storage.set('USER', response.data);
this.modalController.dismiss();
} else{
loading2.dismiss();
}
}else{
//show error msg
}
}, (err) => {
console.log('upload err ::',err);
});
}
});
}
}
async imageuserchoose(sourceType){
const options: CameraOptions = {
quality: 76,
sourceType: sourceType,
destinationType: this.camera.DestinationType.FILE_URI,
encodingType: this.camera.EncodingType.JPEG,
mediaType: this.camera.MediaType.PICTURE,
saveToPhotoAlbum: true,
correctOrientation: true,
// allowEdit: true,
}
this.camera.getPicture(options).then((imageData) => {
let filename,path;
this.imagepic = imageData;
if (sourceType === this.camera.PictureSourceType.PHOTOLIBRARY) {
path = imageData.substring(0, imageData.lastIndexOf('/') + 1);
filename = imageData.substring(imageData.lastIndexOf('/') + 1);
let index = filename.indexOf('?');
if (index > -1) {
filename = filename.substring(0,index);
}
}
if (sourceType === this.camera.PictureSourceType.CAMERA) {
filename = imageData.substring(imageData.lastIndexOf('/') + 1);
path = imageData.substring(0, imageData.lastIndexOf('/') + 1);
console.log(path,'FileName::', filename);
}
this.fileUploadName=filename;
this.file.readAsDataURL(path, filename).then(data => {
this.userdetailsedit.patchValue({
profile_pic: data,
});
});
}, (err) => {
// Handle error
});
}
This will solve your problem.
Related
So, I have looked through the docs and answers on here and I'm still needing some help:
index.tsx
const getInfiniteArticles = ({ pageParams = 0 }) => {
const res = await axios.get('/api/articles', { params: { page: pageParams } });
return res.data;
}
api/articles.ts
const getArticles = async (req: NextApiRequest, res: NextApiResponse) => {
try {
const { page } = req.query;
const pageNum = Number(page);
const data = await NewsService.getArticles(getRange(pageNum));
return res.status(200).json({
data,
previousPage: pageNum > 0 ? (pageNum - 1) : null,
nextPage: pageNum + 1,
});
} catch (err) {
res.json(err);
res.status(405).end();
}
};
export default getArticles;
index.tsx
const { data: articlePages, fetchNextPage } = useInfiniteQuery(
'infinite-articles',
getInfiniteArticles,
{
getNextPageParam: (lastPage, allGroups) => {
console.log('lastPage: ', lastPage);
console.log('allGroups: ', allGroups);
return lastPage.nextPage;
}
});
const handleLoadMore = () => {
fetchNextPage();
};
console after clicking next page:
lastPage: { data: Array(50), previousPage: null, nextPage: 1}
allGroups: [
{ data: Array(50), previousPage: null, nextPage: 1},
{ data: Array(50), previousPage: null, nextPage: 1},
]
Any help on why I'm getting the same groups is appreciated! :)
So, it turns out my structure wasn't correct
const {
fetchNextPage,
fetchPreviousPage,
hasNextPage,
hasPreviousPage,
isFetchingNextPage,
isFetchingPreviousPage,
...result
} = useInfiniteQuery(queryKey, ({ pageParam = 1 }) => fetchPage(pageParam), {
...options,
getNextPageParam: (lastPage, allPages) => lastPage.nextCursor,
getPreviousPageParam: (firstPage, allPages) => firstPage.prevCursor,
})
queryFn: (context: QueryFunctionContext) => Promise<TData>
The queryFn is supposed to be a synchronous function that returns a Promise
I was either passing an async function or I was returning the TData not a promise.
updated and working:
const getInfiniteArticles = ({ pageParam = 0 }) => axios.get('/api/articles', { params: { page: pageParam } });
const { data: articlePages, fetchNextPage } = useInfiniteQuery('articles', getInfiniteArticles, {
getNextPageParam: (lastPage, pages) => {
// the returned axios response
return lastPage.data.nextPage;
}
});
Reference Page
i'm working on app witch i need to send multiple images,
and i wonder if there is any way to send multiple images via file transfer plugin,
this my code:
const options: CameraOptions = {
quality: 100,
destinationType: this.camera.DestinationType.FILE_URI,
sourceType: this.camera.PictureSourceType.PHOTOLIBRARY
}
this.camera.getPicture(options).then((imageData2) => {
this.imageURI2 = imageData2;
}, (err) => {
console.log(err);
});
upload
const fileTransfer: FileTransferObject = this.transfer.create();
let options: FileUploadOptions = {
fileKey: 'file',
fileName: 'name.jpg',
headers: {
Connection: "close"
}
}
options.chunkedMode = false;
if(this.imageURI1 != null){
fileTransfer.upload(this.imageURI1,
'https://test.test.com/uplaodphoto.php', options)
.then((data) => {
alert("success");
this.imageFileName1 =
"https://test.test.com/images/name.jpg"
}, (err) => {
alert("error"+JSON.stringify(err));
});
User Image Picker Plugin Cordova Image Picker
Usage:
import { ImagePicker } from '#ionic-native/image-picker';
constructor(private imagePicker: ImagePicker) { }
export class YourPage {
pickImages(){
this.imagePicker.getPictures(options).then((results) => {
for (var i = 0; i < results.length; i++) {
console.log('Image URI: ' + results[i]);
this.imageUpload(results[i])
}
}, (err) => { });
}
// Upload Image function.
imageUpload(path) {
const fileTransfer: FileTransferObject = this.transfer.create();
let options: FileUploadOptions = {
fileKey: 'image',
fileName: '.png',
chunkedMode: false,
//mimeType: "image/jpeg",
}
fileTransfer.upload(path, 'https://api.com/image-upload', options)
.then((data) => {
console.log(data+" Uploaded Successfully");
let res = JSON.parse(data.response);
if (res.success == true) {
}
this.loader.dismiss();
}, (err) => {
console.log(err);
});
}
}
I am working with ionic 3 framework.and i don't know how to convert base64 image to blob Thank you.
.ts file
openCamera() {
let actionSheet = this.actionSheetCtrl.create({
title: 'Edit Your Profile Picture',
buttons: [
{
text:'Camera',
icon: 'ios-camera',
role: 'destructive',
handler: () => {
const options: CameraOptions = {
quality: 100,
destinationType: this.camera.DestinationType.DATA_URL,
saveToPhotoAlbum: true,
mediaType: this.camera.MediaType.PICTURE
}
this.camera.getPicture(options).then((imageData) => {
this.image = 'data:image/jpeg;base64,' + imageData;
}, (err) => {
alert(err)
});
}
},
{
text: 'Gallery',
icon: 'ios-images',
handler: () => {
const options: CameraOptions = {
quality: 50,
destinationType: this.camera.DestinationType.DATA_URL,
encodingType: this.camera.EncodingType.JPEG,
mediaType: this.camera.MediaType.PICTURE,
correctOrientation: true,
sourceType:this.camera.PictureSourceType.PHOTOLIBRARY,
}
this.camera.getPicture(options).then((imageData) => {
// imageData is either a base64 encoded string or a file URI
// If it's base64 (DATA_URL):
this.image = 'data:image/jpeg;base64,' + imageData;
//this.image = base64Image;
// alert(base64Image);
}, (err) => {
// Handle error
console.log(err);
});
}
},
{
text: 'Cancel',
role: 'cancel',
handler: () => {
}
}
]
});
actionSheet.present();
}
.html file
<img (click)="openCamera()" [src]="domSanitizer.bypassSecurityTrustUrl(image)" class="before-img" >
Default setting is the file URI (blob) according to this:
https://ionicframework.com/docs/native/camera/#CameraOptions
So you can alter your current options here to request FILE URI instead of DATA URL (as your current options set to use DATA URL which is base64):
const options: CameraOptions = {
quality: 50,
destinationType: this.camera.DestinationType.FILE_URI,
encodingType: this.camera.EncodingType.JPEG,
mediaType: this.camera.MediaType.PICTURE,
correctOrientation: true,
sourceType:this.camera.PictureSourceType.PHOTOLIBRARY,
}
You can also omit setting this explicitly and then in theory the default will be used...
I tried testing my ionic image upload app in browser but since I can not upload image due to cordova_not_available been displayed on the screen, every time I click ed on the upload button this error pop up Cannot read property 'split' of undefined
**
NewpostPage.html:51 ERROR ReferenceError: FileTransfer is not defined at new Transfer (VM1294 vendor.js:149642) at NewpostPage.webpackJsonp.162.NewpostPage.uploadPhoto (VM1295 main.js:601) at Object.eval [as handleEvent] (VM1527 NewpostPage.ngfactory.js:180) at handleEvent (VM1294 vendor.js:13963) at callWithDebugContext (VM1294 vendor.js:15472) at Object.debugHandleEvent [as handleEvent] (VM1294 vendor.js:15059) at dispatchEvent (VM1294 vendor.js:10378) at VM1294 vendor.js:11003 at HTMLButtonElement. (VM1294 vendor.js:39326) at t.invokeTask (VM1427 polyfills.js:3)
**
in my upload.ts i have this
uploadPhoto() {
let loader = this.loadingCtrl.create({
content: "Please wait..."
});
loader.present();
//let filename = this.imagePath.split('/').pop();
console.log('this.imagePath: ', this.imagePath)
let filename = this.imagePath;
let options = {
fileKey: "file",
fileName: filename,
chunkedMode: false,
mimeType: "image/jpg",
params: {'location': this.location, 'title': this.postTitle, 'description': this.desc }
};
const fileTransfer = new Transfer();
fileTransfer.upload(this.imageNewPath, AppSettings.API_UPLOAD_ENDPOINT,
options).then((entry) => {
this.imagePath = '';
this.imageChosen = 0;
loader.dismiss();
this.navCtrl.setRoot(IncidentsPage);
}, (err) => {
alert(JSON.stringify(err));
});
}
chooseImage() {
let actionSheet = this.actionSheet.create({
title: 'Choose Picture Source',
buttons: [
{
text: 'Gallery',
icon: 'albums',
handler: () => {
this.actionHandler(1);
}
},
{
text: 'Camera',
icon: 'camera',
handler: () => {
this.actionHandler(2);
}
},
{
text: 'Cancel',
role: 'cancel',
handler: () => {
console.log('Cancel clicked');
}
}
]
});
actionSheet.present();
}
//}
actionHandler(selection: any) {
var options: any;
if (selection == 1) {
options = {
quality: 75,
destinationType: Camera.DestinationType.FILE_URI,
sourceType: Camera.PictureSourceType.PHOTOLIBRARY,
allowEdit: true,
encodingType: Camera.EncodingType.JPEG,
targetWidth: 500,
targetHeight: 500,
saveToPhotoAlbum: false
};
} else {
options = {
quality: 75,
destinationType: Camera.DestinationType.FILE_URI,
sourceType: Camera.PictureSourceType.CAMERA,
allowEdit: true,
encodingType: Camera.EncodingType.JPEG,
targetWidth: 500,
targetHeight: 500,
saveToPhotoAlbum: false
};
}
Camera.getPicture(options).then((imgUrl) => {
var sourceDirectory = imgUrl.substring(0, imgUrl.lastIndexOf('/') + 1);
var sourceFileName = imgUrl.substring(imgUrl.lastIndexOf('/') + 1, imgUrl.length);
sourceFileName = sourceFileName.split('?').shift();
File.copyFile(sourceDirectory, sourceFileName, cordova.file.externalApplicationStorageDirectory, sourceFileName).then((result: any) => {
this.imagePath = imgUrl;
this.imageChosen = 1;
this.imageNewPath = result.nativeURL;
}, (err) => {
alert(JSON.stringify(err));
})
}, (err) => {
alert(JSON.stringify(err))
});
}
Please help out.
I think i see what you are asking now.
You need to check for undefined and "" before running the code inside uploadPhoto().
uploadPhoto() {
if(this.imagePath !== undefined || this.imagePath !== '') {
let loader = this.loadingCtrl.create({
content: "Please wait..."
});
loader.present();
//let filename = this.imagePath.split('/').pop();
console.log('this.imagePath: ', this.imagePath)
let filename = this.imagePath;
let options = {
fileKey: "file",
fileName: filename,
chunkedMode: false,
mimeType: "image/jpg",
params: {'location': this.location, 'title': this.postTitle, 'description': this.desc }
};
const fileTransfer = new Transfer();
fileTransfer.upload(this.imageNewPath, AppSettings.API_UPLOAD_ENDPOINT,
options).then((entry) => {
this.imagePath = '';
this.imageChosen = 0;
loader.dismiss();
this.navCtrl.setRoot(IncidentsPage);
}, (err) => {
alert(JSON.stringify(err));
});
}
} else {
//do something else
}
I'm getting an error when i pick a photo from the gallery its showing the alert as "server error". Please help me with my problem >_< I'm using Image Picker and cordova file transfer
upload(){
ImagePicker.getPictures({
maximumImagesCount: 1,
width: 127,
height: 127,
quality: 75
}).then((results) => {
for (var i = 0; i < results.length; i++) {
var url = "http://ifund.esy.es/register.php"
var targetPath = results[i];
// File name only
var filename = targetPath.split("/").pop();
const fileTransfer = new Transfer();
var options = {
fileKey: "file",
fileName: filename,
chunkedMode: false,
mimeType: "image/jpg",
params: {'directory': 'upload', 'fileName': filename, 'username': this.username, 'password': this.password, 'first_name': this.fname, 'last_name': this.lname, 'email': this.email, 'address': this.address, 'contact': this.contact, 'bday': this.bday}
};
fileTransfer.upload(url, targetPath, options).then((results) => {
alert('file uploaded successfully ' + results);
}, error => {
alert('server error');
});
}
}, (err) => {
let alert = this.alert.create({
title:'Warning',
subTitle: "ERROR",
buttons: ['OK']
})
alert.present(); });