Can you please describe in more detail what you are fundamentally trying to achieve? I think that in general this thread is seeking for a way to do something that is best avoided entirely.
Absolutely. So I have my main app check for authentication via the ionic services auth plugin, then if they are authorized it loads the āTabPageā which is nothing more than just a tab placeholder to have my main app in a tabbed view. Here is the āTabsPageā htmlā¦
<ion-tabs>
<ion-tab tabTitle="Home" tabIcon="home" [root]="homeTab"></ion-tab>
<ion-tab tabTitle="Search" tabIcon="search" [root]="searchTab"></ion-tab>
<ion-tab tabTitle="Post" tabIcon="add" [root]="addPostTab"></ion-tab>
<ion-tab tabTitle="Settings" tabIcon="cog" [root]="settingsTab"></ion-tab>
<ion-tab tabTitle="Profile" tabIcon="person" [root]="profileTab"></ion-tab>
</ion-tabs>
Very simple layout, just tabs. Then in my AddPost page I am trying to grab a hold of the input in it with ā@viewChildā. Here is the html of my āAddPostPageāā¦
<ion-header>
<ion-navbar>
<ion-title text-center>Add Post</ion-title>
</ion-navbar>
</ion-header>
<ion-content>
<img src="{{pathForImage(lastImage)}}" style="width: 100%;" [hidden]="lastImage === null" id="imageSrc">
<h3 [hidden]="lastImage !== null">Please select an image</h3>
<ion-buttons>
<button ion-button icon-left (click)="showOptions()">
<ion-icon name="camera"></ion-icon>
Select Image
</button>
</ion-buttons>
<ion-list>
<ion-item>
<ion-label floating>Title</ion-label>
<ion-input [(ngModel)]="post.title" type="text"></ion-input>
</ion-item>
<ion-item>
<ion-label floating>Content</ion-label>
<ion-input [(ngModel)]="post.content" type="text"></ion-input>
</ion-item>
</ion-list>
</ion-content>
<ion-footer>
<button (click)="save()" color="light" ion-button full>Save</button>
</ion-footer>
Then for my AddPost ts file I am using the ā@ViewChildā to try to grab that input. And here is the AddPostPage ts fileā¦
import {Component, ElementRef, ViewChild} from '@angular/core';
import {
IonicPage, NavController, NavParams, Platform,
Loading, ToastController, LoadingController, ActionSheetController
} from 'ionic-angular';
import { User } from '@ionic/cloud-angular';
import { Post } from '../../providers/post';
import { File } from '@ionic-native/file';
import { FileChooser } from '@ionic-native/file-chooser';
import {Transfer, TransferObject} from '@ionic-native/transfer';
import { FilePath } from '@ionic-native/file-path';
import { Camera } from '@ionic-native/camera';
import { PostModel } from '../../models/PostModel';
import { Data } from '../../providers/data';
import {Tabs} from "../tabs/tabs";
import Cropper from 'cropperjs';
declare var cordova: any;
@IonicPage()
@Component({
selector: 'page-add-post-page',
templateUrl: 'add-post-page.html',
})
export class AddPostPage {
@ViewChild('imageSrc') imageElement: ElementRef;
loading: Loading;
post: PostModel = new PostModel();
activeTab: number = 2;
lastImage: any = null;
load: any;
cropperInstance: any;
constructor(
public navCtrl: NavController,
public navParams: NavParams,
public postService: Post,
public user: User,
public platform: Platform,
public imageUploader: ImageUploader,
public toastCtrl: ToastController,
public dataService: Data,
public loader: LoadingController,
public pushService: PushService,
public actionSheetCtrl: ActionSheetController,
private camera: Camera,
private transfer: Transfer,
private filePath: FilePath,
private file: File,
private fileChooser: FileChooser
) {
}
pathForImage(img) {
return this.imageUploader.pathForImage(img);
}
ionViewDidLoad() {
this.imageUploader.setType('post');
}
showOptions() {
this.presentActionSheet();
// this.imageUploader.getLastImage().subscribe(data => this.lastImage = data);
}
getPicture(sourceType) {
this.imageUploader.takePicture(sourceType).then(data => {
this.cropImage();
// this.lastImage = data;
});
}
cropImage() {
console.log("Cropping image");
console.log(this.imageElement.nativeElement);
this.cropperInstance = new Cropper(this.imageElement.nativeElement, {
aspectRatio: 1/1,
dragMode: 'move',
modal: true,
guides: false,
highlight: false,
background: false,
autoCrop: true,
autoCropArea: 0.9,
responsive: false,
zoomable: true,
movable: false
});
}
presentActionSheet() {
let actionSheet = this.actionSheetCtrl.create({
title: 'Select Image Source',
buttons: [
{
text: 'Load from Library',
handler: () => {
if(this.platform.is('android') || this.platform.is('ios')) {
this.camera.getPicture({
quality: 100,
destinationType: this.camera.DestinationType.FILE_URI,
sourceType: this.camera.PictureSourceType.PHOTOLIBRARY,
encodingType: this.camera.EncodingType.JPEG,
mediaType: this.camera.MediaType.PICTURE,
allowEdit: false,
correctOrientation: true
}).then(imageData => {
console.log(this.imageElement);
console.log(this);
console.log(imageData);
this.imageElement.nativeElement.src = imageData;
this.cropImage();
})
// this.takePicture(this.camera.PictureSourceType.PHOTOLIBRARY);
} else {
this.fileChooser.open().then(uri => {
this.imageElement.nativeElement.src = uri;
this.cropImage();
// let currentName = uri.substr(uri.lastIndexOf('/') + 1),
// currentPath = uri.substr(0, uri.lastIndexOf('/') + 1),
// name = this.user.details.username + '-' + new Date().getTime() + '.jpg';
// this.copyFileToLocalDir(currentPath, currentName, name);
});
}
}
},
{
text: 'Use Camera',
handler: () => {
this.camera.getPicture({
quality: 100,
destinationType: this.camera.DestinationType.FILE_URI,
sourceType: this.camera.PictureSourceType.CAMERA,
encodingType: this.camera.EncodingType.PNG,
mediaType: this.camera.MediaType.PICTURE,
allowEdit: false,
correctOrientation: true
}).then((imageData) => {
this.imageElement.nativeElement.src = imageData;
this.cropImage();
})
}
},
{
text: 'Cancel',
role: 'cancel'
}
]
});
actionSheet.present();
}
copyFileToLocalDir(namePath, currentName, newName) {
return new Promise(resolve => {
this.file.copyFile(namePath, currentName, cordova.file.dataDirectory, newName).then(success => {
this.lastImage = newName;
resolve(newName);
}, error => {
this.presentToast('Error while storing file.');
console.log(error);
resolve(false);
});
});
}
presentToast(text) {
let toast = this.toastCtrl.create({
message: text,
duration: 3500,
position: 'top'
});
toast.present();
}
cropDone() {
this.lastImage = this.cropperInstance.getCroppedCanvas({width: 500, height: 500}).toDataURL('image/jpeg');
this.imageUploader.setImage(this.lastImage);
}
save() {
this.showLoader('Uploading...');
let toast, targetUsers = this.post.getTargetUsers();
this.post._id = this.post.title.toLowerCase().replace(/ /g, '-').replace(/[^\w-]+/g, '');
this.post.datePublished = new Date().toISOString();
this.post.dateUpdated = new Date().toISOString();
this.post.author = this.user.details.username;
this.post.author_id = this.user.id;
this.post.avatar = this.user.details.image;
this.post.image = this.imageUploader.lastImage;
this.post.tags = this.post.getPostTags();
; this.postService.addPost(this.post.toObject()).then(data => {
if(data) {
this.imageUploader.uploadImage(this.post._id).then(([success, response]) => {
if(success) {
if(targetUsers.length > 0) {
this.pushService.sendPostNotification(targetUsers, this.user.details).then(data => {
this.load.dismissAll();
this.navCtrl.setRoot(Tabs);
});
}
this.load.dismissAll();
this.navCtrl.setRoot(Tabs);
} else {
this.load.dismissAll();
toast = this.toastCtrl.create({
message: "Unable to upload the post image.",
duration: 3500,
position: 'top'
});
toast.present();
}
});
} else {
this.load.dismissAll();
toast = this.toastCtrl.create({
message: "Unable to upload the new post.",
duration: 3500,
position: 'top'
});
toast.present();
}
});
}
showLoader(message) {
this.load = this.loader.create({
content: message
});
this.load.present();
}
}
So, as you can see I am trying to get the img tag in my view page and fill it in after the user crops the image. However, after I select an image, in the dev console in chrome I am getting an error saying that imageElement is undefined. I just want to get that img element so I can dynamically change the image, and because the plugin, the only one I could find for ionic 2, all others were written in ionic 1, needs that to build the display for the cropping functions, but it is always undefined.
The gentleman above was saying that it had something to do with the tabs, and had a link to a version he said was working, but the link doesnāt work, so I was hoping he had an updated link, or at least an example of how he made it work. I canāt figure out how to get my ā@ViewChildā to not be undefined.
Thank you so much, I seriously appreciate it. I am still kind of new to ionic and this is my first app I have built, so I am still learning best practices and such.
On a side note, I know I should be using a provider or something else to handle uploading images, and I plan to create one after I get this part figured out. Since I am going to be uploading images on more than just this page.