CKEditor 5 Image Upload Issues












5















I'm using ckeditor5 into my project. I have to support image upload so I have search and followed this stackoverflow article.



I have created an uploadAdapter which is:



class UploadAdapter {

constructor( loader, url, t ) {
this.loader = loader;
this.url = url;
this.t = t;
}

upload() {
return new Promise( ( resolve, reject ) => {
this._initRequest();
this._initListeners( resolve, reject );
this._sendRequest();
} );
}

abort() {
if ( this.xhr ) {
this.xhr.abort();
}
}

_initRequest() {
const xhr = this.xhr = new XMLHttpRequest();

xhr.open( 'POST', this.url, true );
xhr.responseType = 'json';
}

_initListeners( resolve, reject ) {
const xhr = this.xhr;
const loader = this.loader;
const t = this.t;
const genericError = t( 'Cannot upload file:' ) + ` ${ loader.file.name }.`;

xhr.addEventListener( 'error', () => reject( genericError ) );
xhr.addEventListener( 'abort', () => reject() );
xhr.addEventListener( 'load', () => {
const response = xhr.response;

if ( !response || !response.uploaded ) {
return reject( response && response.error && response.error.message ? response.error.message : genericError );
}
resolve( {
default: response.url
} );
} );

if ( xhr.upload ) {
xhr.upload.addEventListener( 'progress', evt => {
if ( evt.lengthComputable ) {
loader.uploadTotal = evt.total;
loader.uploaded = evt.loaded;
}
} );
}
}

_sendRequest() {
const data = new FormData();
data.append( 'upload', this.loader.file );
this.xhr.send( data );
}
}

import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
import FileRepository from '@ckeditor/ckeditor5-upload/src/filerepository';
export default class GappUploadAdapter extends Plugin {
static get requires() {
return [ FileRepository ];
}

static get pluginName() {
return 'GappUploadAdapter';
}

init() {
const url = this.editor.config.get( 'gapp.uploadUrl' );

if ( !url ) {
return;
}

this.editor.plugins.get( FileRepository ).createUploadAdapter = loader => new UploadAdapter( loader, url, this.editor.t );
}
}


Now this is explained. I have 2 issues.




  1. Once uploaded ( my upload on server is working fine and returning a valid url in format {default: url}, why is my image content inserted as data-uri and not in url as for easy image demo here. I want my image to be url like.

  2. I would like to listen for a kind of success upload image ( with image id retrieved from upload server call ) to insert some content in my page. How to proceed ?
    enter image description hereenter image description here


Thanks for help.



PS: I'm building ckeditor with command 'npm run build' from git repo cloned from https://github.com/ckeditor/ckeditor5-build-classic



EDIT:
Thanks to accepted response, I saw that I was wrong in returned data. I was not returning any URL in my uploader front end which was causing editor image to stay in img-data way. Once valid URL was returned, it was parsed automatically and my editor image was containing a valid url.



image descr










share|improve this question





























    5















    I'm using ckeditor5 into my project. I have to support image upload so I have search and followed this stackoverflow article.



    I have created an uploadAdapter which is:



    class UploadAdapter {

    constructor( loader, url, t ) {
    this.loader = loader;
    this.url = url;
    this.t = t;
    }

    upload() {
    return new Promise( ( resolve, reject ) => {
    this._initRequest();
    this._initListeners( resolve, reject );
    this._sendRequest();
    } );
    }

    abort() {
    if ( this.xhr ) {
    this.xhr.abort();
    }
    }

    _initRequest() {
    const xhr = this.xhr = new XMLHttpRequest();

    xhr.open( 'POST', this.url, true );
    xhr.responseType = 'json';
    }

    _initListeners( resolve, reject ) {
    const xhr = this.xhr;
    const loader = this.loader;
    const t = this.t;
    const genericError = t( 'Cannot upload file:' ) + ` ${ loader.file.name }.`;

    xhr.addEventListener( 'error', () => reject( genericError ) );
    xhr.addEventListener( 'abort', () => reject() );
    xhr.addEventListener( 'load', () => {
    const response = xhr.response;

    if ( !response || !response.uploaded ) {
    return reject( response && response.error && response.error.message ? response.error.message : genericError );
    }
    resolve( {
    default: response.url
    } );
    } );

    if ( xhr.upload ) {
    xhr.upload.addEventListener( 'progress', evt => {
    if ( evt.lengthComputable ) {
    loader.uploadTotal = evt.total;
    loader.uploaded = evt.loaded;
    }
    } );
    }
    }

    _sendRequest() {
    const data = new FormData();
    data.append( 'upload', this.loader.file );
    this.xhr.send( data );
    }
    }

    import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
    import FileRepository from '@ckeditor/ckeditor5-upload/src/filerepository';
    export default class GappUploadAdapter extends Plugin {
    static get requires() {
    return [ FileRepository ];
    }

    static get pluginName() {
    return 'GappUploadAdapter';
    }

    init() {
    const url = this.editor.config.get( 'gapp.uploadUrl' );

    if ( !url ) {
    return;
    }

    this.editor.plugins.get( FileRepository ).createUploadAdapter = loader => new UploadAdapter( loader, url, this.editor.t );
    }
    }


    Now this is explained. I have 2 issues.




    1. Once uploaded ( my upload on server is working fine and returning a valid url in format {default: url}, why is my image content inserted as data-uri and not in url as for easy image demo here. I want my image to be url like.

    2. I would like to listen for a kind of success upload image ( with image id retrieved from upload server call ) to insert some content in my page. How to proceed ?
      enter image description hereenter image description here


    Thanks for help.



    PS: I'm building ckeditor with command 'npm run build' from git repo cloned from https://github.com/ckeditor/ckeditor5-build-classic



    EDIT:
    Thanks to accepted response, I saw that I was wrong in returned data. I was not returning any URL in my uploader front end which was causing editor image to stay in img-data way. Once valid URL was returned, it was parsed automatically and my editor image was containing a valid url.



    image descr










    share|improve this question



























      5












      5








      5








      I'm using ckeditor5 into my project. I have to support image upload so I have search and followed this stackoverflow article.



      I have created an uploadAdapter which is:



      class UploadAdapter {

      constructor( loader, url, t ) {
      this.loader = loader;
      this.url = url;
      this.t = t;
      }

      upload() {
      return new Promise( ( resolve, reject ) => {
      this._initRequest();
      this._initListeners( resolve, reject );
      this._sendRequest();
      } );
      }

      abort() {
      if ( this.xhr ) {
      this.xhr.abort();
      }
      }

      _initRequest() {
      const xhr = this.xhr = new XMLHttpRequest();

      xhr.open( 'POST', this.url, true );
      xhr.responseType = 'json';
      }

      _initListeners( resolve, reject ) {
      const xhr = this.xhr;
      const loader = this.loader;
      const t = this.t;
      const genericError = t( 'Cannot upload file:' ) + ` ${ loader.file.name }.`;

      xhr.addEventListener( 'error', () => reject( genericError ) );
      xhr.addEventListener( 'abort', () => reject() );
      xhr.addEventListener( 'load', () => {
      const response = xhr.response;

      if ( !response || !response.uploaded ) {
      return reject( response && response.error && response.error.message ? response.error.message : genericError );
      }
      resolve( {
      default: response.url
      } );
      } );

      if ( xhr.upload ) {
      xhr.upload.addEventListener( 'progress', evt => {
      if ( evt.lengthComputable ) {
      loader.uploadTotal = evt.total;
      loader.uploaded = evt.loaded;
      }
      } );
      }
      }

      _sendRequest() {
      const data = new FormData();
      data.append( 'upload', this.loader.file );
      this.xhr.send( data );
      }
      }

      import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
      import FileRepository from '@ckeditor/ckeditor5-upload/src/filerepository';
      export default class GappUploadAdapter extends Plugin {
      static get requires() {
      return [ FileRepository ];
      }

      static get pluginName() {
      return 'GappUploadAdapter';
      }

      init() {
      const url = this.editor.config.get( 'gapp.uploadUrl' );

      if ( !url ) {
      return;
      }

      this.editor.plugins.get( FileRepository ).createUploadAdapter = loader => new UploadAdapter( loader, url, this.editor.t );
      }
      }


      Now this is explained. I have 2 issues.




      1. Once uploaded ( my upload on server is working fine and returning a valid url in format {default: url}, why is my image content inserted as data-uri and not in url as for easy image demo here. I want my image to be url like.

      2. I would like to listen for a kind of success upload image ( with image id retrieved from upload server call ) to insert some content in my page. How to proceed ?
        enter image description hereenter image description here


      Thanks for help.



      PS: I'm building ckeditor with command 'npm run build' from git repo cloned from https://github.com/ckeditor/ckeditor5-build-classic



      EDIT:
      Thanks to accepted response, I saw that I was wrong in returned data. I was not returning any URL in my uploader front end which was causing editor image to stay in img-data way. Once valid URL was returned, it was parsed automatically and my editor image was containing a valid url.



      image descr










      share|improve this question
















      I'm using ckeditor5 into my project. I have to support image upload so I have search and followed this stackoverflow article.



      I have created an uploadAdapter which is:



      class UploadAdapter {

      constructor( loader, url, t ) {
      this.loader = loader;
      this.url = url;
      this.t = t;
      }

      upload() {
      return new Promise( ( resolve, reject ) => {
      this._initRequest();
      this._initListeners( resolve, reject );
      this._sendRequest();
      } );
      }

      abort() {
      if ( this.xhr ) {
      this.xhr.abort();
      }
      }

      _initRequest() {
      const xhr = this.xhr = new XMLHttpRequest();

      xhr.open( 'POST', this.url, true );
      xhr.responseType = 'json';
      }

      _initListeners( resolve, reject ) {
      const xhr = this.xhr;
      const loader = this.loader;
      const t = this.t;
      const genericError = t( 'Cannot upload file:' ) + ` ${ loader.file.name }.`;

      xhr.addEventListener( 'error', () => reject( genericError ) );
      xhr.addEventListener( 'abort', () => reject() );
      xhr.addEventListener( 'load', () => {
      const response = xhr.response;

      if ( !response || !response.uploaded ) {
      return reject( response && response.error && response.error.message ? response.error.message : genericError );
      }
      resolve( {
      default: response.url
      } );
      } );

      if ( xhr.upload ) {
      xhr.upload.addEventListener( 'progress', evt => {
      if ( evt.lengthComputable ) {
      loader.uploadTotal = evt.total;
      loader.uploaded = evt.loaded;
      }
      } );
      }
      }

      _sendRequest() {
      const data = new FormData();
      data.append( 'upload', this.loader.file );
      this.xhr.send( data );
      }
      }

      import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
      import FileRepository from '@ckeditor/ckeditor5-upload/src/filerepository';
      export default class GappUploadAdapter extends Plugin {
      static get requires() {
      return [ FileRepository ];
      }

      static get pluginName() {
      return 'GappUploadAdapter';
      }

      init() {
      const url = this.editor.config.get( 'gapp.uploadUrl' );

      if ( !url ) {
      return;
      }

      this.editor.plugins.get( FileRepository ).createUploadAdapter = loader => new UploadAdapter( loader, url, this.editor.t );
      }
      }


      Now this is explained. I have 2 issues.




      1. Once uploaded ( my upload on server is working fine and returning a valid url in format {default: url}, why is my image content inserted as data-uri and not in url as for easy image demo here. I want my image to be url like.

      2. I would like to listen for a kind of success upload image ( with image id retrieved from upload server call ) to insert some content in my page. How to proceed ?
        enter image description hereenter image description here


      Thanks for help.



      PS: I'm building ckeditor with command 'npm run build' from git repo cloned from https://github.com/ckeditor/ckeditor5-build-classic



      EDIT:
      Thanks to accepted response, I saw that I was wrong in returned data. I was not returning any URL in my uploader front end which was causing editor image to stay in img-data way. Once valid URL was returned, it was parsed automatically and my editor image was containing a valid url.



      image descr







      ckeditor5 easyimage






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 30 '18 at 13:19







      franchez

















      asked Nov 20 '18 at 16:45









      franchezfranchez

      434619




      434619
























          1 Answer
          1






          active

          oldest

          votes


















          3





          +50









          If the data-uri is still used after successful upload I would assume that server response was not processed correctly and the received url could not be retrieved. I have tested adapter code you provided and it works fine (with CKFinder on server side). I would check how the upload server response looks and if it can be correctly parsed.



          When using CKFinder you will see:



          enter image description here



          and a parsed JSON response:



          enter image description here



          You could check if response is processed correctly in your adapter in:



          xhr.addEventListener( 'load', () => {
          const response = xhr.response;
          ...
          }




          Listening to successful image upload may be tricky as there is no event directly related to it. Depending on what exactly you are trying to achieve you may try to extend you custom loader so when successful response is received (and resolve() called) you may execute some code. However, in this state the image element is still not updated (in model, view and DOM) with new URL and UploadAdapter lacks a direct access to editor instance so it may be hard to do anything complex.



          Better way may be to listen to model changes, the similar way it is done in ImageUploadEditing plugin (see code here) checking the image uploadStatus attribute change:






          editor.model.document.on( 'change', () => {
          const changes = doc.differ.getChanges();

          for ( const entry of changes ) {
          const uploaded = entry.type === 'attribute' && entry.attributeNewValue === 'complete' && entry.attributeOldValue === 'uploading';

          console.log( entry );
          }
          } );





          If it changes from uploading to complete it means the images was successfully uploaded:



          enter image description here



          You may also take a look at another answer, which shows how to hook into FileRepository API to track entire upload process - https://github.com/ckeditor/ckeditor5-image/issues/243#issuecomment-442393578.






          share|improve this answer



















          • 1





            Thanks dude. I followed your steps and finally found my issue.

            – franchez
            Nov 30 '18 at 13:21











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53397679%2fckeditor-5-image-upload-issues%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          3





          +50









          If the data-uri is still used after successful upload I would assume that server response was not processed correctly and the received url could not be retrieved. I have tested adapter code you provided and it works fine (with CKFinder on server side). I would check how the upload server response looks and if it can be correctly parsed.



          When using CKFinder you will see:



          enter image description here



          and a parsed JSON response:



          enter image description here



          You could check if response is processed correctly in your adapter in:



          xhr.addEventListener( 'load', () => {
          const response = xhr.response;
          ...
          }




          Listening to successful image upload may be tricky as there is no event directly related to it. Depending on what exactly you are trying to achieve you may try to extend you custom loader so when successful response is received (and resolve() called) you may execute some code. However, in this state the image element is still not updated (in model, view and DOM) with new URL and UploadAdapter lacks a direct access to editor instance so it may be hard to do anything complex.



          Better way may be to listen to model changes, the similar way it is done in ImageUploadEditing plugin (see code here) checking the image uploadStatus attribute change:






          editor.model.document.on( 'change', () => {
          const changes = doc.differ.getChanges();

          for ( const entry of changes ) {
          const uploaded = entry.type === 'attribute' && entry.attributeNewValue === 'complete' && entry.attributeOldValue === 'uploading';

          console.log( entry );
          }
          } );





          If it changes from uploading to complete it means the images was successfully uploaded:



          enter image description here



          You may also take a look at another answer, which shows how to hook into FileRepository API to track entire upload process - https://github.com/ckeditor/ckeditor5-image/issues/243#issuecomment-442393578.






          share|improve this answer



















          • 1





            Thanks dude. I followed your steps and finally found my issue.

            – franchez
            Nov 30 '18 at 13:21
















          3





          +50









          If the data-uri is still used after successful upload I would assume that server response was not processed correctly and the received url could not be retrieved. I have tested adapter code you provided and it works fine (with CKFinder on server side). I would check how the upload server response looks and if it can be correctly parsed.



          When using CKFinder you will see:



          enter image description here



          and a parsed JSON response:



          enter image description here



          You could check if response is processed correctly in your adapter in:



          xhr.addEventListener( 'load', () => {
          const response = xhr.response;
          ...
          }




          Listening to successful image upload may be tricky as there is no event directly related to it. Depending on what exactly you are trying to achieve you may try to extend you custom loader so when successful response is received (and resolve() called) you may execute some code. However, in this state the image element is still not updated (in model, view and DOM) with new URL and UploadAdapter lacks a direct access to editor instance so it may be hard to do anything complex.



          Better way may be to listen to model changes, the similar way it is done in ImageUploadEditing plugin (see code here) checking the image uploadStatus attribute change:






          editor.model.document.on( 'change', () => {
          const changes = doc.differ.getChanges();

          for ( const entry of changes ) {
          const uploaded = entry.type === 'attribute' && entry.attributeNewValue === 'complete' && entry.attributeOldValue === 'uploading';

          console.log( entry );
          }
          } );





          If it changes from uploading to complete it means the images was successfully uploaded:



          enter image description here



          You may also take a look at another answer, which shows how to hook into FileRepository API to track entire upload process - https://github.com/ckeditor/ckeditor5-image/issues/243#issuecomment-442393578.






          share|improve this answer



















          • 1





            Thanks dude. I followed your steps and finally found my issue.

            – franchez
            Nov 30 '18 at 13:21














          3





          +50







          3





          +50



          3




          +50





          If the data-uri is still used after successful upload I would assume that server response was not processed correctly and the received url could not be retrieved. I have tested adapter code you provided and it works fine (with CKFinder on server side). I would check how the upload server response looks and if it can be correctly parsed.



          When using CKFinder you will see:



          enter image description here



          and a parsed JSON response:



          enter image description here



          You could check if response is processed correctly in your adapter in:



          xhr.addEventListener( 'load', () => {
          const response = xhr.response;
          ...
          }




          Listening to successful image upload may be tricky as there is no event directly related to it. Depending on what exactly you are trying to achieve you may try to extend you custom loader so when successful response is received (and resolve() called) you may execute some code. However, in this state the image element is still not updated (in model, view and DOM) with new URL and UploadAdapter lacks a direct access to editor instance so it may be hard to do anything complex.



          Better way may be to listen to model changes, the similar way it is done in ImageUploadEditing plugin (see code here) checking the image uploadStatus attribute change:






          editor.model.document.on( 'change', () => {
          const changes = doc.differ.getChanges();

          for ( const entry of changes ) {
          const uploaded = entry.type === 'attribute' && entry.attributeNewValue === 'complete' && entry.attributeOldValue === 'uploading';

          console.log( entry );
          }
          } );





          If it changes from uploading to complete it means the images was successfully uploaded:



          enter image description here



          You may also take a look at another answer, which shows how to hook into FileRepository API to track entire upload process - https://github.com/ckeditor/ckeditor5-image/issues/243#issuecomment-442393578.






          share|improve this answer













          If the data-uri is still used after successful upload I would assume that server response was not processed correctly and the received url could not be retrieved. I have tested adapter code you provided and it works fine (with CKFinder on server side). I would check how the upload server response looks and if it can be correctly parsed.



          When using CKFinder you will see:



          enter image description here



          and a parsed JSON response:



          enter image description here



          You could check if response is processed correctly in your adapter in:



          xhr.addEventListener( 'load', () => {
          const response = xhr.response;
          ...
          }




          Listening to successful image upload may be tricky as there is no event directly related to it. Depending on what exactly you are trying to achieve you may try to extend you custom loader so when successful response is received (and resolve() called) you may execute some code. However, in this state the image element is still not updated (in model, view and DOM) with new URL and UploadAdapter lacks a direct access to editor instance so it may be hard to do anything complex.



          Better way may be to listen to model changes, the similar way it is done in ImageUploadEditing plugin (see code here) checking the image uploadStatus attribute change:






          editor.model.document.on( 'change', () => {
          const changes = doc.differ.getChanges();

          for ( const entry of changes ) {
          const uploaded = entry.type === 'attribute' && entry.attributeNewValue === 'complete' && entry.attributeOldValue === 'uploading';

          console.log( entry );
          }
          } );





          If it changes from uploading to complete it means the images was successfully uploaded:



          enter image description here



          You may also take a look at another answer, which shows how to hook into FileRepository API to track entire upload process - https://github.com/ckeditor/ckeditor5-image/issues/243#issuecomment-442393578.






          editor.model.document.on( 'change', () => {
          const changes = doc.differ.getChanges();

          for ( const entry of changes ) {
          const uploaded = entry.type === 'attribute' && entry.attributeNewValue === 'complete' && entry.attributeOldValue === 'uploading';

          console.log( entry );
          }
          } );





          editor.model.document.on( 'change', () => {
          const changes = doc.differ.getChanges();

          for ( const entry of changes ) {
          const uploaded = entry.type === 'attribute' && entry.attributeNewValue === 'complete' && entry.attributeOldValue === 'uploading';

          console.log( entry );
          }
          } );






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 28 '18 at 11:05









          f1amesf1ames

          1,14011333




          1,14011333








          • 1





            Thanks dude. I followed your steps and finally found my issue.

            – franchez
            Nov 30 '18 at 13:21














          • 1





            Thanks dude. I followed your steps and finally found my issue.

            – franchez
            Nov 30 '18 at 13:21








          1




          1





          Thanks dude. I followed your steps and finally found my issue.

          – franchez
          Nov 30 '18 at 13:21





          Thanks dude. I followed your steps and finally found my issue.

          – franchez
          Nov 30 '18 at 13:21




















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53397679%2fckeditor-5-image-upload-issues%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Guess what letter conforming each word

          Port of Spain

          Run scheduled task as local user group (not BUILTIN)