Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get response from CKEditor Upload #2833

Closed
WandersonAlves opened this issue Dec 22, 2017 · 8 comments
Closed

Get response from CKEditor Upload #2833

WandersonAlves opened this issue Dec 22, 2017 · 8 comments
Labels
package:upload pending:feedback This issue is blocked by necessary feedback.

Comments

@WandersonAlves
Copy link

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!

@Reinmar
Copy link
Member

Reinmar commented Dec 22, 2017

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?

@WandersonAlves
Copy link
Author

@Reinmar Oh, this makes sense.

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

Thanks for the help!

@Reinmar
Copy link
Member

Reinmar commented Dec 26, 2017

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.

@WandersonAlves
Copy link
Author

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 😭

@WandersonAlves
Copy link
Author

Update:

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

Thanks all!

@Reinmar
Copy link
Member

Reinmar commented Dec 29, 2017

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.

@mlewand mlewand transferred this issue from ckeditor/ckeditor5-upload Oct 9, 2019
@mlewand mlewand added pending:feedback This issue is blocked by necessary feedback. resolution:solved package:upload labels Oct 9, 2019
@robclancy
Copy link

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.

@bsor-dev
Copy link

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)
      }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
package:upload pending:feedback This issue is blocked by necessary feedback.
Projects
None yet
Development

No branches or pull requests

5 participants