My task is to upload a file. Seams easy but apparently is not :confused
Using:
Cordova deprecated the FileTransfer plugin. So I tried to upload images taken with the Camera plugin without it. Actually uploading a file with angular’s httpClient is pretty easy. However converting a local file into a blob was all but straight forward. There is a cordova blog post , which explains how it is done.
The javascript code is however not very suitable for angular. I ended up with following code:
private uploadFile(serverurl: string, filePath: string): Observable<boolean> {
…
Tried to use code above but still is not working. Can somebody provide a working solution? Would really appreciate.
the code I have looks like that:
`this.fileChooser.open().then((fileuri) => {
this.filePath.resolveNativePath(fileuri).then(resolvedNativePath => {
return from(this.file.resolveLocalFilesystemUrl(resolvedNativePath)).pipe(
mergeMap((fileEntry: FileEntry) => {
// wrap callback into observable
return new Observable((observer: Observer<any>) => {
fileEntry.file(file => {
const name = file.name;
const reader = new FileReader();
reader.onloadend = () => {
const imgBlob = new Blob([reader.result], {type: file.type});
observer.next([imgBlob, name]);
observer.complete();
};
reader.readAsArrayBuffer(file);
});
});
}),
mergeMap(([imgBlob, name]) => {
alert(imgBlob);
alert(name);
const formData = new FormData();
formData.append('file', imgBlob, name);
return of([]);
})
);
});
});`
Is that really true, or is that an overspecification of what your actual task is? The reason I ask this is that you link to a thread that says:
If what you’re really trying to do is upload images taken from a camera, then it’s rather inefficient to even write them to a file, let alone then read them again, along with several rounds of base64 encoding and decoding.
Instead, ask Camera
to give you a Uri as documented here , ask Angular’s HttpClient
to fetch that Uri with a responseType
of blob
as documented here , make a FormData
object as documented here , stuff the Blob
in it, and fire off a POST
request with that FormData
as the payload.
Thank you for the answer! My task is to upload files like pdfs not images using post method. This is what I have for now:
html file:
<ion-button (click)="pickFile()">documents</ion-button>
page file:
constructor(
private file: File,
private fileChooser: FileChooser,
private filePath: FilePath,
private fileOpener: FileOpener,
private store: Store<fromDocuments.State>,
) {
}
pickFile() {
this.fileChooser.open().then((fileuri) => {
this.filePath.resolveNativePath(fileuri).then(resolvedNativePath => {
this.file.resolveLocalFilesystemUrl(resolvedNativePath)
.then((entry: FileEntry) => {
(entry).file(file => this.readFile(entry));
})
.catch(err => {
});
});
});
}
async readFile(file: FileEntry) {
const path = file.nativeURL.substr(0, file.nativeURL.lastIndexOf('/') + 1);
// testing if is possible to open a given file
this.fileOpener.open(file.nativeURL, 'application/pdf')
.then(() => alert('File is opened'))
.catch(e => alert(`Error openening file ${JSON.stringify(e)}`));
try {
const buffer = await this.file.readAsArrayBuffer(path, file.name);
alert('buffer');
const fileBlob = new Blob([buffer], {type: 'application/pdf'});
} catch (error) {
alert(`Buffering failed ${JSON.stringify(error)}`)
} finally {
alert('finally');
}
}
despite that the fileOpener opens a file without any problems alert(‘buffer’) is never fired. Furthermore neither catch nor finally blocks are fired as well. I was using following tutorial:
https://devdactic.com/upload-ionic-files-firebase-storage/
any hints why it does not work?
Party it solved the problem:
pickFile() {
this.fileChooser.open().then((fileuri) => {
this.filePath.resolveNativePath(fileuri).then(resolvedNativePath => {
this.file.resolveLocalFilesystemUrl(resolvedNativePath)
.then((entry: FileEntry) => {
(entry).file(file => this.readFile(entry));
})
.catch(err => {
});
});
});
}
async readFile(file: FileEntry) {
let contents = null;
try {
contents = await Filesystem.readFile({
path: file.nativeURL,
// directory: FilesystemDirectory.Documents,
// encoding: FilesystemEncoding.UTF8
});
if (!contents) {
return;
}
return this.post
.post('Document',
{
Document: contents.data,
DossierId: 4163,
Libelle: 'rocket star',
AssistantId: 11
}, {}).then(result => {
alert('result');
alert(JSON.stringify(result));
})
.catch(er => {
alert('er');
alert(JSON.stringify(er));
});
} catch (err) {
alert('err');
alert(err);
}
}
Unfortunately contents.data seams not to be a valid base64 format, any hints please to convert it to the stream that is required by the api endpoint?