Ckeditor5-react: CKEditorContext calls onReady callback twice

Created on 28 Sep 2020  Â·  7Comments  Â·  Source: ckeditor/ckeditor5-react

CKEditorContext#onReady is being called twice after loading a page and restarting itself.

A snippet that reproduces the issue:

import React, { Component } from 'react';

import { CKEditor, CKEditorContext } from '@ckeditor/ckeditor5-react';

import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor';
import Essentials from '@ckeditor/ckeditor5-essentials/src/essentials';
import Bold from '@ckeditor/ckeditor5-basic-styles/src/bold';
import Italic from '@ckeditor/ckeditor5-basic-styles/src/italic';
import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
import Context from '@ckeditor/ckeditor5-core/src/context';
import ContextPlugin from '@ckeditor/ckeditor5-core/src/contextplugin';
import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';

let isContextError = false;
let isPluginError = false;

class CustomContextPlugin extends ContextPlugin {
    init() {
        console.log( 'CustomContextPlugin#init()' );
        if ( !isContextError ) {
            isContextError = true;
            setTimeout( () => {
                console.log( 'Throwing an error: "CustomContextPlugin".' );
                throw new CKEditorError( 'custom-context-plugin-random-error', this.context );
            }, 3000 );
        }
    }
}

class CustomPlugin extends Plugin {
    init() {
        console.log( 'CustomPlugin#init()' );
        if ( !isPluginError ) {
            isPluginError = true;
            setTimeout( () => {
                console.log( 'Throwing an error: "CustomPlugin".' );
                throw new CKEditorError( 'custom-plugin-random-error', this.context );
            }, 5000 );
        }
    }
}

const editorConfiguration = {
  plugins: [ Essentials, Bold, Italic, Paragraph, CustomPlugin ],
  toolbar: [ 'bold', 'italic' ]
};

const conextConfiguration = {
    plugins: [
        CustomContextPlugin
    ]
};

class App extends Component {
  render() {
    return (
        <div className="App">
          <h2>Using CKEditor 5 from source in React</h2>
            <CKEditorContext
                context={ Context }
                config={ conextConfiguration }
                onReady={ context => {
                    console.log( 'CKEditorContext: Ready.', context );
                } }
                onError={ ( err, data ) => {
                    console.log( 'CKEditorContext: Error.', err, data );
                } }
            >
              <CKEditor
                  editor={ ClassicEditor }
                  config={ editorConfiguration }
                  data="<p>Hello from CKEditor 5!</p>"
                  onReady={ editor => {
                    console.log( 'Editor is ready to use (1)!', editor );
                  } }
                  onChange={ ( event, editor ) => {
                    const data = editor.getData();
                    console.log( { event, editor, data } );
                  } }
                  onError={ ( err, data ) => {
                      console.log( 'CKEditor (1): Error.', err, data );
                  } }
              />
                <CKEditor
                    editor={ ClassicEditor }
                    config={ editorConfiguration }
                    data="<p>Hello from CKEditor 5!</p>"
                    onReady={ editor => {
                        // You can store the "editor" and use when it is needed.
                        console.log( 'Editor is ready to use (2)!', editor );
                    } }
                    onChange={ ( event, editor ) => {
                        const data = editor.getData();
                        console.log( { event, editor, data } );
                    } }
                    onError={ ( err, data ) => {
                        console.log( 'CKEditor (2): Error.', err, data );
                    } }
                />
            </CKEditorContext>
        </div>
    );
  }
}

export default App;

And the console logs:

image

And what I figured out – content from editors will be overwritten with the value of the #data property when restarting. I would expect that the content will be saved and restored after restarting part.

bug devops integrations

All 7 comments

Simplified scenario. A context without editors:

class App extends Component {
  render() {
    return (
        <div className="App">
          <h2>Using CKEditor 5 from source in React</h2>
            <CKEditorContext
                context={ Context }
                config={ conextConfiguration }
                onReady={ context => {
                    console.log( 'CKEditorContext: Ready.', context );
                } }
                onError={ ( err, data ) => {
                    console.log( 'CKEditorContext: Error.', err, data );
                } }
            >
            </CKEditorContext>
        </div>
    );
  }
}

image

It looks like the context feature is being created twice.

Somewhere I asked whether the CKEditorContext#onError callback will be called if an error occurred in an editor. Yes, it will.

image

But something is wrong here. See the error options in callbacks:

Context: {phase: "runtime", willContextRestart: true}
Editor: {phase: "runtime", willEditorRestart: undefined}

The error occurred in the editor. I would expect that the editor will restart itself and it somehow will trigger the context component.

The current implementation restarts everything if an error occurred in the context or editor component.

I'll check if the context component is for sure created twice - if that's the case I'll fix it. But I'd move the error callback calls to the follow-up since it's not something critical.

It looks like the context feature is being created twice.

Hm, I can't reproduce it.

These issues are hard to reproduce without using some ugly code that makes errors during the initialization etc. The Watchdog feature isn't designed to catch such things and what's more important, this is not a regression.

We're also seeing the same issue as @pomek where the content from editors will be overwritten with the value of the #data property when restarting. We're using it with the collaboration feature.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

amanshu-kataria picture amanshu-kataria  Â·  12Comments

chhatch picture chhatch  Â·  9Comments

Softwareschmiede picture Softwareschmiede  Â·  6Comments

c1trons picture c1trons  Â·  7Comments

Slasherio picture Slasherio  Â·  8Comments