Search code examples
angularckeditor5mention

CKEditor mention plugin with customised output failing on Angular 9


I have Ckeditor working with my Angular app and I was originally on Angular 7. I built the editor using their online builder instead of using ckeditor classic. I am using the mentions plugin and customised the output so that I have my mention in an a tag with data I need instead of a span with the mention name.

After updating to Angular 9, the editor and mentions still work but it fails if I use the customised output.

If I use the customised output, this is the error I get.

core.js:6241 ERROR Error: Uncaught (in promise): TypeError: t is not a constructor
TypeError: t is not a constructor
at ckeditor.js:1978
at Array.map (<anonymous>)
at w (ckeditor.js:1978)
at wa.init (ckeditor.js:1947)
at PF.initPlugins (ckeditor.js:10026)
at ckeditor.js:12377
at new ZoneAwarePromise (zone-evergreen.js:960)
at Function.create (ckeditor.js:12377)
at CKEditorComponent.<anonymous> (ckeditor-ckeditor5-angular.js:232)
at Generator.next (<anonymous>)
at resolvePromise (zone-evergreen.js:798)
at resolvePromise (zone-evergreen.js:750)
at zone-evergreen.js:860
at ZoneDelegate.invokeTask (zone-evergreen.js:399)
at Object.onInvokeTask (core.js:41675)
at ZoneDelegate.invokeTask (zone-evergreen.js:398)
at Zone.runTask (zone-evergreen.js:167)
at drainMicroTaskQueue (zone-evergreen.js:569)
at ZoneTask.invokeTask [as invoke] (zone-evergreen.js:484)
at invokeTask (zone-evergreen.js:1621)

This is how I have configured the editor.

    import * as Editor from '@assets/ckeditor5/build/ckeditor';

export class CkeditorComponent {
  public editor = Editor;
  editorConfig = {
    extraPlugins: [this.mentionCustomization],
    toolbar: {
      items: [
        ...
      ],
    },
    mention: {
      feeds: [
        {
          marker: '@',
          feed: this.getUsers.bind(this),
        },
      ],
    },
    language: 'en-gb',
  };


  mentionCustomization(editor) {
    editor.conversion.for('upcast').elementToAttribute({
      view: {
        name: 'a',
        key: 'data-mention',
        classes: 'mention',
        attributes: {
          href: true,
          'data-user-id': true,
        },
      },
      model: {
        key: 'mention',
        value: (viewItem) => editor.plugins.get('Mention').toMentionAttribute(viewItem),
      },
      converterPriority: 'high',
    });

    editor.conversion.for('downcast').attributeToElement({
      model: 'mention',
      view: (modelAttributeValue, { writer }) => {
        if (!modelAttributeValue) {
          return;
        }

        // eslint-disable-next-line consistent-return
        return writer.createAttributeElement('a', {
          class: 'mention',
          'data-user-id': modelAttributeValue.userId,
          href: 'javascript:void(0)',
        }, {
          priority: 20,
          id: modelAttributeValue.uid,
        });
      },
      converterPriority: 'high',
    });
  }
}

This was working with the same code before I upgraded from 7 to 9. The only information I have come up with for this is this github post and I haven't been able to work out the fix.

Thanks for any help.


Solution

  • I Found the answer after some trial and error and examples of ckeditor. For some reason, there is still a problem with Angular 9 and even though it didn't throw any errors, the mentions still would not work. Fortunately, I was only going through 9 to upgrade to 11.

    I removed the extraPlugins from the editorConfig and added a new function to initialise the mentionCustomization function.

    editorConfig = {
      extraPlugins: [this.mentionCustomization], // deleted this
        toolbar: {
          items: [
            ...
          ],
        },
    }
    

    onEditorReady(editor) {
      this.mentionCustomization(editor);
    }
    

    In the HTML add this new function to the ready output for ckeditor

    <ckeditor [formControlName]="formCtrlName"
              [editor]="editor"
              [config]="editorConfig"
              (ready)="onEditorReady($event)"></ckeditor>