Ionic Framework : #ionic/angular 5.5.2
#angular-devkit/build-angular : 0.1100.7
#angular-devkit/schematics : 10.0.8
#angular/cli : 10.0.8
#ionic/angular-toolkit : 2.3.3
Capacitor:
Capacitor CLI : 2.4.5
#capacitor/core : 2.4.5
Utility:
cordova-res : not installed
native-run : 1.3.0
I've been trying to let the user add images from the camera or gallery using this tutorial
(https://enappd.com/blog/camera-and-image-picker-in-ionic-apps/148/). When I run the application on the emulator, the error message (from ToastController) said 'plugin_not_installed'.
page1.ts
import { Camera, CameraOptions } from "#ionic-native/Camera/ngx";
import { File } from "#ionic-native/file/ngx";
export class Page1 extends OnInit(){
constructor(
private camera: Camera,
private actionSheetController: ActionSheetController,
private file: File
){}
async pickImage(sourceType) {
const options: CameraOptions = {
quality: 100,
sourceType: sourceType,
destinationType: this.camera.DestinationType.FILE_URI,
encodingType: this.camera.EncodingType.PNG,
mediaType: this.camera.MediaType.PICTURE,
};
await this.camera.getPicture(options).then(
(imageData) => {
console.log(imageData);
// imageData is either a base64 encoded string or a file URI
if (imageData !== undefined)
this.img = "data:image/jpeg;base64," + imageData;
},
(err) => {
this.presentToast(err);
}
);
}
async selectImage() {
const actionSheet = await this.actionSheetController.create({
header: "Select Image source",
buttons: [
{
text: "From Gallery",
handler: () => {
this.pickImage(this.camera.PictureSourceType.PHOTOLIBRARY);
},
},
{
text: "From Camera",
handler: () => {
this.pickImage(this.camera.PictureSourceType.CAMERA);
},
},
{
text: "Cancel",
role: "cancel",
},
],
});
return await actionSheet.present();
}
page1.html
<ion-card id="pictureFrame" (click)="selectImage()">
</ion-card>
downgrading to "onesignal-cordova-plugin": "^2.11.4" worked for me
Related
I am trying to preview a JasperReports Server report through Axios, the problem is that when I run it (localhost:port) it keeps loading and does nothing, any help on this?
const express = require('express')
const axios = require("axios")
const app = express()
app.get('/', async function(req,res){
try {
const url = "http://localhost:8080/jasperserver/rest_v2/reports/Re013.pdf"
const params = {
AMB_OCULTO : "123",
AMB : "123",
INS : "FF",
ORD_INI: "419435",
ORD_FIN: "419435"
}
const file = await axios.get(url, {
params: params,
responseType: "stream",
auth:{
username: "jasperadmin",
password: "jasperadmin"
}
})
res.writeHead(200,{"Content-Type":"application/pdf"})
file.data.pipe(res)
} catch (error) {
console.log(error)
}
})
app.listen(4000,()=>{
console.log('')
})
Nothing happens when I call the getPicture function with: this.camera.PictureSourceType.PHOTOLIBRARY.
Hower it does work in Android just not iOs and also this.camera.PictureSourceType.CAMERA does work in iOs.
private cameraOptions: CameraOptions = {
quality: 50,
destinationType: this.camera.DestinationType.DATA_URL,
encodingType: this.camera.EncodingType.JPEG,
mediaType: this.camera.MediaType.PICTURE,
};
public async changeProfilePicture() {
const sheet = await this.actionSheet.create({
buttons: [{
text: 'Camera',
handler: () => {
this.takePicture();
},
},
{
text: 'Foto album',
handler: () => {
this.choosePicture();
},
}
, {
text: 'Annuleren',
role: 'cancel',
handler: () => {
sheet.dismiss();
},
}],
});
sheet.present();
}
private async takePicture() {
try {
const image = await this.camera.getPicture({
...this.cameraOptions,
sourceType: this.camera.PictureSourceType.CAMERA,
});
this.userService.editProfilePicture(`data:image/jpeg;base64,${image}`).subscribe(user => {
this.user = user;
});
} catch (err) {
this.handleImageError(err);
}
}
private async choosePicture() {
try {
const image = await this.camera.getPicture({
...this.cameraOptions,
sourceType: this.camera.PictureSourceType.PHOTOLIBRARY,
});
this.userService.editProfilePicture(`data:image/jpeg;base64,${image}`).subscribe(user => {
this.user = user;
});
} catch (err) {
this.handleImageError(err);
}
}
iOS requires permissions to be configured when accessing certain native features. In your case, you need to set the NSPhotoLibraryUsageDescription key in the Info.plist file of your app. You can manually edit this file within the xcode project, but it's better to place this in the config.xml of your ionic project :
<config-file parent="NSPhotoLibraryUsageDescription" platform="ios" target="*-Info.plist">
<string>The app needs access to your library to...</string>
</config-file>
I am using Ionic 4 AlertController to create an alert that lets a user add a task. The issue is, that until a user clicks on the date input, no date shows. I have tried adding both a min and max as well.
Code is as follows
async addCustomTask() {
const alert = await this.alertController.create({
header: 'Add custom task',
inputs: [
{
name: 'task',
type: 'text',
placeholder: 'I would like to..'
},
{
name: 'dueDate',
type: 'date'
}
],
buttons: [
{
text: 'Cancel',
role: 'cancel',
cssClass: 'secondary',
handler: () => {
return false;
}
}, {
text: 'Ok',
handler: (data) => {
this.addTask(data.task, moment.tz(data.dueDate, this.account.timezone));
}
}
]
});
await alert.present();
};
Looks like this when it loads up
The moment you click it, it all begins to work as needed. It submits as a date as well, in the correct format.
Ionic:
ionic (Ionic CLI) : 4.10.3 (/Users/sam/.nvm/versions/node/v11.0.0/lib/node_modules/ionic)
Ionic Framework : #ionic/angular 4.0.0-rc.0
#angular-devkit/build-angular : 0.8.9
#angular-devkit/schematics : 0.8.9
#angular/cli : 6.2.9
#ionic/angular-toolkit : 1.2.2
Cordova:
cordova (Cordova CLI) : 8.1.2 (cordova-lib#8.1.1)
Cordova Platforms : ios 4.5.5
Cordova Plugins : cordova-plugin-ionic-keyboard 2.1.3, cordova-plugin-ionic-webview 2.4.0, (and 11 other plugins)
System:
NodeJS : v11.0.0 (/Users/sam/.nvm/versions/node/v11.0.0/bin/node)
npm : 6.4.1
OS : macOS Mojave
Xcode : Xcode 10.1 Build version 10B61
My Current Ionic version is 4.12.0, needed an alert-popup to take input from user StartDate and EndDate from the user for a filter. What I learned is that it allows you to add the "date" type HOWEVER, it only supports "STRING" for value & max values. Also, remember not to mix the input types. The following is my code
private format_date(dt: any) {
var today = new Date(dt);
let dd: any = today.getDate();
let mm: any = today.getMonth() + 1;
const yyyy = today.getFullYear();
if (dd < 10) {
dd = `0${dd}`;
}
if (mm < 10) {
mm = `0${mm}`;
}
return `${yyyy}-${mm}-${dd}`;
}
async presentPopover() {
const dt = new Date();
this.firstDate = dt.getFullYear() + '-' + ((dt.getMonth() + 1) < 10 ? '0' + (dt.getMonth() + 1) : (dt.getMonth() + 1) ) + '-01';
this.maxDate = this.format_date(dt);
this.lastDay = new Date(dt.getFullYear(), dt.getMonth() + 2, 0);
this.lastDay = this.format_date(this.lastDay);
if(new Date(this.lastDay) > dt) {
this.lastDay = this.format_date(dt);
}
const alerts = await this.alertController.create({
header: 'Filter',
inputs: [
{
name: 'fromDt',
type: 'date',
value: this.firstDate,
max: this.maxDate
},
{
name: 'toDt',
type: 'date',
value: this.lastDay,
max: this.maxDate
}
],
buttons:
[
{
text: 'Cancel',
role: 'cancel',
cssClass: 'secondary',
handler: () => {
console.log('Confirm Cancel');
}
},
{
text: 'Ok',
handler: () => {
console.log('Confirm Ok');
this.fetchData();
}
}
]
});
await alerts.present();
}
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 am using PDFMake for creating the pdf with my predefined Document definition. In my old ionic 1 project, I am passing the encoded string to print function which works fine. here is the code for old ionic 1
var dd = $scope.createDocumentDefinition();
$timeout(function () {
var pdf = pdfMake.createPdf(dd);
pdf.getBase64(function (encodedString) {
console.log(encodedString);
$ionicLoading.hide();
window.plugins.PrintPDF.print({
data: encodedString,
type: 'Data',
title: 'Print Document',
success: function () {
console.log('success');
},
error: function (data) {
data = JSON.parse(data);
console.log('failed: ' + data.error);
}
});
});
}, 1000);
Now I am upgrading my project to Ionic 3 so I tried the same thing but the output is different here is my new ionic 3 code. printer open but instead of printing as per my document definition it just prints the encoded string.
let printer_ = this.printer;
var dd = this.createDocumentDefinition();
var pdf = pdfMake.createPdf(dd);
pdf.getBase64(function (_encodedString) {
let options: PrintOptions = {
name: 'MyDocument'
};
console.log(JSON.stringify(pdf));
printer_.print(_encodedString, options).then((msg)=>{
console.log("Success",msg);
},(error) => {
console.log("Error", error);
});
});
Any idea how to use this in ionic 3 ??
You can use pdfmake for generate PDF using ionic.
First you need to install plugin for file and file opener.
ionic cordova plugin add cordova-plugin-file-opener2
ionic cordova plugin add cordova-plugin-file
After that install NPM package of file, FileOpener and PDF make
npm install pdfmake
npm install #ionic-native/file-opener
npm install #ionic-native/file
Open your src/app.module.ts and include file and fileoperner reference:
import { File } from '#ionic-native/file';
import { FileOpener } from '#ionic-native/file-opener';
Add File and FileOpener in provider
providers: [
StatusBar,
SplashScreen,
{provide: ErrorHandler, useClass: IonicErrorHandler},
File,
FileOpener
]
I am generating a template UI looks like this:
<ion-header>
<ion-navbar>
<ion-title>
Ionic PDF
</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<ion-item>
<ion-label stacked>From</ion-label>
<ion-input [(ngModel)]="letterObj.from"></ion-input>
</ion-item>
<ion-item>
<ion-label stacked>To</ion-label>
<ion-input [(ngModel)]="letterObj.to"></ion-input>
</ion-item>
<ion-item>
<ion-label stacked>Text</ion-label>
<ion-textarea [(ngModel)]="letterObj.text" rows="10"></ion-textarea>
</ion-item>
<button ion-button full (click)="createPdf()">Create PDF</button>
<button ion-button full (click)="downloadPdf()" color="secondary" [disabled]="!pdfObj">Download PDF</button>
</ion-content>
After that your home.component.ts code looks like this:
import { Component } from '#angular/core';
import { NavController, Platform } from 'ionic-angular';
import pdfMake from 'pdfmake/build/pdfmake';
import pdfFonts from 'pdfmake/build/vfs_fonts';
pdfMake.vfs = pdfFonts.pdfMake.vfs;
import { File } from '#ionic-native/file';
import { FileOpener } from '#ionic-native/file-opener';
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
letterObj = {
to: '',
from: '',
text: ''
}
pdfObj = null;
constructor(public navCtrl: NavController, private plt: Platform, private file: File, private fileOpener: FileOpener) { }
createPdf() {
var docDefinition = {
content: [
{ text: 'REMINDER', style: 'header' },
{ text: new Date().toTimeString(), alignment: 'right' },
{ text: 'From', style: 'subheader' },
{ text: this.letterObj.from },
{ text: 'To', style: 'subheader' },
this.letterObj.to,
{ text: this.letterObj.text, style: 'story', margin: [0, 20, 0, 20] },
{
ul: [
'Bacon',
'Rips',
'BBQ',
]
}
],
styles: {
header: {
fontSize: 18,
bold: true,
},
subheader: {
fontSize: 14,
bold: true,
margin: [0, 15, 0, 0]
},
story: {
italic: true,
alignment: 'center',
width: '50%',
}
}
}
this.pdfObj = pdfMake.createPdf(docDefinition);
}
downloadPdf() {
if (this.plt.is('cordova')) {
this.pdfObj.getBuffer((buffer) => {
var blob = new Blob([buffer], { type: 'application/pdf' });
// Save the PDF to the data Directory of our App
this.file.writeFile(this.file.dataDirectory, 'myletter.pdf', blob, { replace: true }).then(fileEntry => {
// Open the PDf with the correct OS tools
this.fileOpener.open(this.file.dataDirectory + 'myletter.pdf', 'application/pdf');
})
});
} else {
// On a browser simply use download!
this.pdfObj.download();
}
}
}