Ckeditor5: Get response from CKEditor Upload

Created on 22 Dec 2017  Â·  8Comments  Â·  Source: ckeditor/ckeditor5

Hi All!

I wanna know if is possible to get the response from my server after the upload is complete.

Currently, i have something like this:

editor.plugins.get('FileRepository').on('change:uploaded', (result, name, value, oldValue) => {
    console.log(result);        
})

But, all of the four parameters not correspond to the response data.

From a custom adapter, is possible to create a new event to listen, and on this event, return my data?
Thanks!

upload feedback

All 8 comments

Hi! I've read through your question but, TBH, I'm not sure whether I understand what you want to achieve.

My guess is that you want the FileRepository to fire some events when each specific file is uploaded. Currently, FileRepository exposes only uploaded/uploadTotal observable properties. Such information is usually needed to handle "upload UI" of your app – e.g. display a combined upload progress bar (Letters do that for instance). Each upload is handled on its own then and each FileLoader fires its own events.

What I think you may find useful is the FileLoader#uploadResponse property. It's observable, so you can listen to change:uploadResponse. Something like this should work:

const fileRepo = editor.plugins.get( 'FileRepository' );
const fileLoader = fileRepo.getLoader( yourNativeFileInstance );

fileLoader.on( 'change:uploadResponse', ( evt, name, value, oldValue ) => {
    console.log( newValue ); // your data
} );

Does that help?

@Reinmar Oh, this makes sense.

How can i create this File Instance? I don't get this to work :(

Thanks for the help!

I'd need to know more about the feature you want to implement to be able to answer that. Basically, you get files from the paste/drop events – that's what the ImageUpload plugin does. But I don't know whether you want to intercept some other files or use that plugin and extend its functionality.

I created a custom adapter to set some headers and upload the images to a custom url. After the upload is complete, i need to get the response and insert them in a array to later use. I only need to broadcast these responses to my parent component.

Below is my directive to initialize ckeditor 5

import { Directive, ElementRef, EventEmitter, Output, Input, AfterViewInit, OnChanges, SimpleChanges, OnInit } from '@angular/core';
import { environment } from '../../environments/environment';
import ClassicEditor from '@ckeditor/ckeditor5-build-classic';
import { Adapter } from './ckeditor-custom-adapter';
import { EventsService } from '../services/event-handler/event-handler.service';
import { FileLoader } from '@ckeditor/ckeditor5-upload/src/filerepository';

@Directive({
    selector: '[ckeditor]',
    providers: [EventsService]
})
export class CkEditorDirective implements OnInit, OnChanges {

    ngOnChanges({ckDisable}: SimpleChanges): void {
        if (this.editor && ckDisable && ckDisable.currentValue) {
            this.editor.isReadOnly = ckDisable.currentValue;
        }
    }

    @Output() change: EventEmitter<string> = new EventEmitter();
    @Input() comuId: string;
    @Input() ckDisable: boolean;

    private editor;

    constructor(private el: ElementRef, private eventService: EventsService) {

    }

    ngOnInit() {
        let isReadOnly = false;
        let config = {
            toolbar: ['headings', 'bold', 'italic', 'link', 'bulletedList', 'numberedList', 'blockQuote', 'insertImage', 'undo', 'redo'],
            ckfinder: {
                uploadUrl: `${environment.endPoint}comunicados_anexos/upload`
            },
            language: 'pt-br',
            image: {
                toolbar: [
                    'imageTextAlternative', 
                    '|', 
                    'imageStyleFull',
                    'imageStyleAlignLeft',
                    'imageStyleAlignCenter',
                    'imageStyleAlignRight'],
                styles: [
                    'imageStyleFull',
                    'imageStyleSide',
                    'imageStyleAlignLeft',
                    'imageStyleAlignCenter',
                    'imageStyleAlignRight'
                ]
            }
        };
        ClassicEditor
        .create(this.el.nativeElement, config)
        .then(editor => {
            const fileRepo = editor.plugins.get('FileRepository');
            // const fileLoader = editor.plugins.get('FileLoader'); ?????
            // const loader = fileRepo.getLoader(fileLoader); ????

            this.editor = editor;
            editor.isReadOnly = this.ckDisable; 
            fileRepo.createAdapter = (loader) => {
                return new Adapter(loader, editor.config.get('ckfinder.uploadUrl'), this.comuId, editor.t);
            };

            // loader.on('change:uploadResponse', (evt, name, value, oldValue) => {
            //  console.log(evt, name, value, oldValue);
            // });

            editor.document.on('changesDone', () => {
                const data: string = editor.getData();
                this.change.emit(data);
            });
            }, 
            (err) => {
                if (err.message.indexOf('TypeError: e.on is not a function') >= 0) {
                    console.log('grr!');
                }       
            }
        );
    }
}

Thanks for your patience 😭

Update:

There is no need for getting response anymore. I made this in another way on back-end side.

Thanks all!

Great to hear that :)

And I think that you could've modified your adapter a bit to not only call resolve() with the data returned from the server but also store them in some "global" variable. So, instead of relying on the editor you could handle it all in your adapter.

It'd be harder if you used one of the existing adapters. I'm 99% sure there would be some other solution but I'd need to think more on it.

This is the first big issue I've had with ckeditor5. Every time I have had to integrate an editor with uploads I need to listen to the uploaded event to do extra steps. This is the default in every editor I've used. But in this case I need to listen to events on the plugins to be able to get the file instance to listen to events on the loader...
Either that or make a custom adapter that fires custom events.

Got same issue using ckeditor 5. This one made me confused or maybe not really working on ckeditor 5

const fileRepo = editor.plugins.get( 'FileRepository' );
const fileLoader = fileRepo.getLoader( yourNativeFileInstance );

fileLoader.on( 'change:uploadResponse', ( evt, name, value, oldValue ) => {
    console.log( newValue ); // your data
} );

instead, I figured out the fileLoader is already on the createUploadAdapter params. And that loader is the one you need to add the event listener

MyCustomUploadAdapterPlugin(editor) {
      editor.plugins.get('FileRepository').createUploadAdapter = (loader) => {
        loader.on('change:uploadResponse', (evt, name, val, oldval) => {
          if(val){
            console.log(val)  // object response {default: image_link }
          }
        })
        return new MyUploadAdapter(loader)
      }
}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

jodator picture jodator  Â·  3Comments

metalelf0 picture metalelf0  Â·  3Comments

pandora-iuz picture pandora-iuz  Â·  3Comments

Reinmar picture Reinmar  Â·  3Comments

pjasiun picture pjasiun  Â·  3Comments