10

This question may have already answers but none of them is Angular specific. Here are some of them

I am using Angular 5 and following this documentation to implement ckeditor5-angular.

But I am having issue with image uploading, when I try uploading image it says in the browser console.

filerepository-no-upload-adapter: Upload adapter is not defined. Read more: https://docs.ckeditor.com/ckeditor5/latest/framework/guides/support/error-codes.html#error-filerepository-no-upload-adapter

I have tried searching for this issue and was able to find a lot of solutions, but literally I couldn't understand a single of them because they were not Angular specific.

Please help how can I upload image.

Adnan Sheikh
  • 760
  • 3
  • 13
  • 27

5 Answers5

13

In component.html file add following code

<ckeditor [editor]="Editor" (ready)="onReady($event)"></ckeditor>

in component.ts file create function onReady(data)

onReady(eventData) {
    eventData.plugins.get('FileRepository').createUploadAdapter = function (loader) {
      console.log(btoa(loader.file));
      return new UploadAdapter(loader);
    };
  }

Add new class called UploadAdapter and add following code:-

export class UploadAdapter {
  private loader;
  constructor(loader: any) {
    this.loader = loader;
    console.log(this.readThis(loader.file));
  }

  public upload(): Promise<any> {
    //"data:image/png;base64,"+ btoa(binaryString) 
    return this.readThis(this.loader.file);
  }

  readThis(file: File): Promise<any> {
    console.log(file)
    let imagePromise: Promise<any> = new Promise((resolve, reject) => {
      var myReader: FileReader = new FileReader();
      myReader.onloadend = (e) => {
        let image = myReader.result;
        console.log(image);
        return { default: "data:image/png;base64," + image };
        resolve();
      }
      myReader.readAsDataURL(file);
    });
    return imagePromise;
  }

}

here default indicate uploaded image url. I have converted file in base64 but you can call server url and upload your file then return server url with same key.

EnjOy CodInG :)

MayankGaur
  • 957
  • 11
  • 22
Kapil Thakkar
  • 840
  • 10
  • 17
7

I used the below seems to work

class UploadAdapter {
   constructor( loader ) {
      this.loader = loader;
   }

   upload() {
      return this.loader.file
            .then( file => new Promise( ( resolve, reject ) => {
                  var myReader= new FileReader();
                  myReader.onloadend = (e) => {
                     resolve({ default: myReader.result });
                  }

                  myReader.readAsDataURL(file);
            } ) );
   };
}
zackhalil
  • 455
  • 3
  • 14
4

I solved this by implementing my own UploadAdapter
if you use Editor.create(),that would create a new editor element, not associate with the angular component

<ckeditor 
[editor]="Editor" 
[(ngModel)]="content"
(ready)="onReady($event)"
>
</ckeditor>

at component.ts

  onReady($event){
    $event.plugins.get('FileRepository').createUploadAdapter = (loader)=> {
      return new UploadAdapter(loader,'',this.http);
    };
  }

UploadAdapter.ts

import { HttpParams, HttpClient } from "@angular/common/http";

export class UploadAdapter {
    constructor(
      private loader,
      public url:string,
      private http:HttpClient
      ) {
    }
//the uploadFile method use to upload image to your server
  uploadFile(file,url?:string,user?:string){
    let name = '';
    url='your api';
    let formData:FormData = new FormData();
    let headers = new Headers();
    name = file.name;
    formData.append('attachment', file, name);
    const dotIndex = name.lastIndexOf('.');
    const fileName  = dotIndex>0?name.substring(0,dotIndex):name;
    formData.append('name', fileName);
    formData.append('source', user);

    headers.append('Content-Type', 'multipart/form-data');
    headers.append('Accept', 'application/json');
    console.log('formData',formData);
    let params = new HttpParams();
    const options = {
        params: params,
        reportProgress: true,
    };
//http post return an observer
//so I need to convert to Promise
    return this.http.post(url,formData,options);
  }
//implement the upload 
  upload() {
      let upload = new Promise((resolve, reject)=>{
        this.loader['file'].then(
            (data)=>{
                this.uploadFile(data,this.url,'test')
                .subscribe(
                    (result)=>{
//resolve data formate must like this
//if **default** is missing, you will get an error
                        **resolve({ default: result['attachment'] })**
                    },
                    (error)=>{
                        reject(data.msg);
                    }
                );
            }
        );
      });
      return upload;
  }
  abort() {
      console.log("abort")
  }
}
anysunflower
  • 140
  • 2
  • 7
  • I am geting error Expression expected **resolve({ default: result['attachment'] })** – BINFAS K Feb 06 '20 at 10:33
  • result['attachment'] that‘s the data format returned by my backend api,you can change to related data format returned by your api – anysunflower Feb 18 '20 at 08:53
2

Thank you for everyone answer. I create code snippet for anyone who want looking the example. But I used ckeditor inline build. Hope it help.

stackblitz

DKKs
  • 375
  • 1
  • 4
  • 8
0

I was trying to use zackhalil's solution. The image was displayed in the editor, but when I get the value to update the database, I just have:

<figure class="image"><img></figure>

To fix this, I changed the following code:

return { default: "data:image/png;base64," + image };
resolve();

to:

resolve({ default: image });
Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
woj1965
  • 11
  • 1