With Base64 image upload adapter, CKEditor encoding image obviously, to Base64 format, and inserts the result as <img src="data:image/png;base64, code... >
. The code could be very long; I want uploaded image URL instead.
In my application, I need below functionality:
async function encodeSingleFileTo64base(targetFile: File): Promise<string> {
const fileReader: FileReader = new FileReader();
fileReader.readAsDataURL(targetFile);
return new Promise<string>((resolve: (encodedFile: string) => void, reject: (error: Error) => void): void => {
fileReader.onload = (filedHasBeenReadEvent: ProgressEvent<FileReader>): void => {
if (filedHasBeenReadEvent.target === null || filedHasBeenReadEvent.target.result === null) {
reject(new Error("Failed to encode the image file."));
return;
}
resolve(String(filedHasBeenReadEvent.target.result));
};
});
}
import AWSAmplifyAPI, { graphqlOperation, GraphQLResult } from "@aws-amplify/api";
async function uploadPhotoAndGetURL(photoBase64: string): Promise<string> {
return (await AWSAmplifyAPI.graphql(graphqlOperation(
`mutation($photoBase64: String!) { uploadPhoto(photoBase64: $photoBase64) }`,
{ photoBase64 }
))).uploadPhoto;
}
src=""
(it is the subject of current question).Here is the solution template from documentation:
class MyUploadAdapter {
constructor( loader ) {
this.loader = loader;
}
upload() {
return loader.file
.then( file => server.upload( file ) );
}
abort() {
server.abortUpload();
}
}
Both encoding and data submitting are async operations.
I has been confused how to do it compatibly with loader.file.then()
.
I can not undestand from suggested solution template how we can receive uploaded image URL and pass it to src
attribute.
First problem: how to chain two async functions in upload() method?
From here: https://thoughtbot.com/blog/chaining-events-like-a-boss
Example:
const timeUserRequest = async () => {
const before = await getCurrentTimeAsync()
await getUserDataViaHttp()
const after = await getCurrentTimeAsync()
return (after - before)
};
Second problem: how to pass recieved URL to CK editor?
How are you making your request? Did you see this example ?
class MyUploadAdapter {
// ...
// Initializes XMLHttpRequest listeners.
_initListeners( resolve, reject, file ) {
const xhr = this.xhr;
const loader = this.loader;
const genericErrorText = `Couldn't upload file: ${ file.name }.`;
xhr.addEventListener( 'error', () => reject( genericErrorText ) );
xhr.addEventListener( 'abort', () => reject() );
xhr.addEventListener( 'load', () => {
const response = xhr.response;
// This example assumes the XHR server's "response" object will come with
// an "error" which has its own "message" that can be passed to reject()
// in the upload promise.
//
// Your integration may handle upload errors in a different way so make sure
// it is done properly. The reject() function must be called when the upload fails.
if ( !response || response.error ) {
return reject( response && response.error ? response.error.message : genericErrorText );
}
// If the upload is successful, resolve the upload promise with an object containing
// at least the "default" URL, pointing to the image on the server.
// This URL will be used to display the image in the content. Learn more in the
// UploadAdapter#upload documentation.
resolve( {
default: response.url
} );
} );
// Upload progress when it is supported. The file loader has the #uploadTotal and #uploaded
// properties which are used e.g. to display the upload progress bar in the editor
// user interface.
if ( xhr.upload ) {
xhr.upload.addEventListener( 'progress', evt => {
if ( evt.lengthComputable ) {
loader.uploadTotal = evt.total;
loader.uploaded = evt.loaded;
}
} );
}
}
}