'How to handle image upload in angular 5 Tiny MCE component?

I am using TinyMCE editor in angular my angular 5 project, and want to handle image uploads, which I am currently not able to do. Here is my current code:

<editor 
  name="questionStatement" 
  apiKey="somekey" 
  [init]='{
    plugins : [
        "advlist autolink lists link image charmap print preview hr anchor pagebreak",
        "searchreplace wordcount visualblocks visualchars code fullscreen",
        "insertdatetime media nonbreaking save table contextmenu directionality",
        "emoticons template paste textcolor colorpicker textpattern"
      ],
      toolbar1: "insertfile undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image", 
      past_date_images: true,
      external_plugins: { tiny_mce_wiris: "https://www.wiris.net/demo/plugins/tiny_mce/plugin.js" },
      toolbar: "tiny_mce_wiris_formulaEditor, tiny_mce_wiris_formulaEditorChemistry"
    }'
  </editor>

I am following this code sample https://codepen.io/nirajmchauhan/pen/EjQLpV , to handle image uploads. I don't understand, how do I pass the file_picker_callback function to the editor in angular ?

Is there any other way, how should I handle the image uploads ?

I have tried reading the documentation, but couldn't find anything. I have been stuck on this problem for a long time and it would be really great, if someone is able to help me with it.



Solution 1:[1]

This is what worked for me (I am using @tinymce/tinymce-angular):

<editor [(ngModel)]="source" [init]="tinymceInit"></editor>

In the Constructor or Init:

...

this.tinymceInit = {
  plugins : [
    "advlist autolink lists link image charmap print preview hr anchor pagebreak",
    "searchreplace wordcount visualblocks visualchars code fullscreen",
    "insertdatetime media nonbreaking save table contextmenu directionality",
    "emoticons template paste textcolor colorpicker textpattern"
  ],
  toolbar : 'formatselect | bold italic strikethrough forecolor backcolor | link | alignleft aligncenter alignright alignjustify  | numlist bullist outdent indent  | removeformat',
  image_advtab : true,
  file_picker_callback : function(cb, value, meta) {
    var input = document.createElement('input');
    input.setAttribute('type', 'file');
    input.setAttribute('accept', 'image/*');

    // Note: In modern browsers input[type="file"] is functional without 
    // even adding it to the DOM, but that might not be the case in some older
    // or quirky browsers like IE, so you might want to add it to the DOM
    // just in case, and visually hide it. And do not forget do remove it
    // once you do not need it anymore.

    input.onchange = function() {
      var file = input.files[0];

      var reader = new FileReader();
      reader.onload = function () {
        // Note: Now we need to register the blob in TinyMCEs image blob
        // registry. In the next release this part hopefully won't be
        // necessary, as we are looking to handle it internally.
        var id = 'blobid' + (new Date()).getTime();
        var blobCache =  tinymce.activeEditor.editorUpload.blobCache;
        var base64 = reader.result.split(',')[1];
        var blobInfo = blobCache.create(id, file, base64);
        blobCache.add(blobInfo);

        // call the callback and populate the Title field with the file name
        cb(blobInfo.blobUri(), { title: file.name });
      };
      reader.readAsDataURL(file);
    };

    input.click();
  }
}

Edit: To add, you can use that functino to upload files as well, as you know. I would much rather have the base64 data for the particular project I am working on.

Solution 2:[2]

Just to clarify, as of 2022, this is the correct way of implementing the image plugin in angular

At the top of your component.ts, declare tinymce

declare let tinymce: any;

In your init configuration, use this file_picker_callback (this one will not trigger any errors in your ts file)

... rest of editor init
plugins: 'image',
toolbar: 'image',
image_advtab: true,
file_picker_callback: function(cb: any, value: any, meta: any) {
  var input = document.createElement('input');
  input.setAttribute('type', 'file');
  input.setAttribute('accept', 'image/*');

  input.onchange = function () {
    var file = input.files[0];
    var reader = new FileReader();
    reader.onload = function () {
      var id = 'blobid' + (new Date()).getTime();
      var blobCache = tinymce.activeEditor.editorUpload.blobCache;
      var base64 = (reader.result as string).split(',')[1];
      var blobInfo = blobCache.create(id, file, base64);
      blobCache.add(blobInfo);
      cb(blobInfo.blobUri(), { title: file.name });
    };
    reader.readAsDataURL(file);
  };

  input.click();
}

You are done :)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Yousof K.
Solution 2