I would like to upload an image to my back-end using FormData, but as Ionic DEVAPP and Ionic VIEW does not support file, file-transfer and file-upload plugins, I need to do it using only Angular Http or HttpClient.
When using DestinationType.FILE_URI, I can get the internal url from the file and display it on a img object, but I can’t create a typescript File object from this url without the native file, file-path and file-transfer plugins.
getImage() {
const options: CameraOptions = {
quality: 100,
destinationType: this.camera.DestinationType.FILE_URI,
sourceType: this.camera.PictureSourceType.PHOTOLIBRARY
}
this.camera.getPicture(options).then((imageData) => {
this.imageURI = this.sanitizer.bypassSecurityTrustUrl(imageData)
}, (err) => {
console.log(err)
this.presentToast(err)
})
using this template
<ion-content padding>
<ion-item>
<p>{{imageFileName}}</p>
<button ion-button color="secondary" (click)="getImage()">Get Image</button>
</ion-item>
<ion-item>
<h4>Image Preview</h4>
<img style="display:block" [src]="imageURI" *ngIf="imageURI" alt="Ionic File" width="300" />
</ion-item>
<ion-item>
<button ion-button (click)="uploadFile()">Upload</button>
</ion-item>
</ion-content>
When using DestinationType.DATA_URL I can display the image but can not create the typescript File object needed with the original file name to append the image to the FormData used on my upload service at my Ionic App.
It seems I can not find a way to create this typescript File object with the original filename from FILE_URI and the base64 encoded data from DATA_URL using the camera.getPicture from the cordova camera native plugin. All posts about this concern solve the issue using file, file-path and file-transfer plugins unsupported in Ionic DevApp and Ionic View.
Service to upload the file to my back-end just uses this approach:
postImage(image: File): Observable<any> {
constformData = new FormData().append('file', image, image.name)
return this.httpClient.post<any>(this.myUrl,formData)
}
Both getImage from component myPage.ts and postImage from uploadservice.ts work fine, but I can’t find a way to create the File object from camera.getPicture imageData.
Can’t understand how to test and modify a project for both iOS and Android without DevApp or get testers on both without Ionic View. Can’t understand why nobody is using image post to a back-end on Ionic View or DevApp.
EDIT
I have found some options to go from imageData (DATA_URL destination type) base64 encoded image to a File object. Some of them using a blob in between, but the outcome is the same:
this.camera.getPicture(options).then((imageData) => {
this.imageURI = this.sanitizer.bypassSecurityTrustUrl("data:image/jpeg;base64," + imageData)
const imageFile = new File([imageData], 'myImage.jpg', { type: 'image/jpeg' })
console.log(fitxer)
}
}
but the resulting File object seem to have some properties misplaced. Inspecting imageFile.name shows an array where the original encoded data is shown, size and start properties are 0 and but seems correct.
File {name: Array(1), localURL: "myImage.jpg", type: Object, lastModified: null, lastModifiedDate: null, …}
main.js:89
end:0
lastModified:null
lastModifiedDate:null
localURL:"myImage.jpg"
name:Array(1) ["/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAEBAQEBAQEBAQEBAQ…"]
size:0
start:0
type:Object {type: "image/jpeg"}
__proto__:Object {slice: , constructor: }
Same file creation process
file = new File ([encoded string], 'placomerc.jpg', {type: 'image/jpeg'})
on an Angular 4 clean project outputs all object’s properties correctly:
File(53607) {name: "placomerc.jpg", lastModified: 1512739184702, lastModifiedDate: Fri Dec 08 2017 14:19:44 GMT+0100 (Hora estándar r…, webkitRelativePath: "", size: 53607, …}
lastModified:1512739184702
lastModifiedDate:Fri Dec 08 2017 14:19:44 GMT+0100 (Hora estándar romance) {}
name:"placomerc.jpg"
size:53607
type:"image/jpeg"
webkitRelativePath:""
__proto__:File {name: <accessor>, lastModified: <accessor>, lastModifiedDate: <accessor>, …}
On a fresh clean new Ionic project, File object creation, even of simple ‘text/plain’ type, outputs a wrong constructed object:
const textfile = new File (['text'], 'text.txt')
console.log(textfile)
File {name: Array(1), localURL: "text.txt", type: null, lastModified: null, lastModifiedDate: null, …}
main.js:91
end:0
lastModified:null
lastModifiedDate:null
localURL:"text.txt"
name:Array(1) ["text"]
size:0
start:0
type:null
__proto__:Object {slice: , constructor: }
So as for now, it seems it’s my misconception about the creation of Object File on typescript/angular Ionic implementation, or a bug in this functionality.
I will keep posting my progress -even without any suggestion from forum staff members- just for possible further searches of Ionic users stuck on this issue.
EDIT 2
I went a step forward to refine the issue. This simple line of code:
const textfile = new File (['text'], 'text.txt', {type: 'text/plain'})
Will generate a diferent outcome on Angular development inspection and on Angular/Ionic inspection.
While on Angular you’ll get what you expect, on Angular/Ionic3 the properties seem misplaced:
File {name: Array(1), localURL: "text.txt", type: Object, lastModified: null, lastModifiedDate: null, …}
end:0
lastModified:null
lastModifiedDate:null
localURL:"text.txt"
name:Array(1) ["text"]
size:0
start:0
type:Object {type: "text/plain"}
__proto__:Object {slice: , constructor: }
as name property is an Array Array(1) [“text”] containing the body of the file, and end, size and start properties are 0.
On Angular 4 the same code outputs a File object with all properties on place and ready to server upload:
File(13) {name: "text.txt", lastModified: 1520684955392, lastModifiedDate: Sat Mar 10 2018 13:29:15 GMT+0100 (Hora estándar r…, webkitRelativePath: "", size: 13, …}
classes.ts:636
lastModified:1520684955392
lastModifiedDate:Sat Mar 10 2018 13:29:15 GMT+0100 (Hora estándar romance) {}
name:"text.txt"
size:13
type:"text/plain"
webkitRelativePath:""
__proto__:File {name: <accessor>, lastModified: <accessor>, lastModifiedDate: <accessor>, …}
Just in case, I have already tried on “Run Android on device” and “Run Browser” (chrome) so I think is not about the technology of the client. Even more as on Angular 4 is working as expected.