0

I am using CKEditor (@ckeditor/ckeditor5-build-classic) for my Angular App. I have an issue when uploading the image from the front end to back end. The back end route runs fine. I tested it on Postman to post an image successfully. But when I use CKFinder to upload image from Ckeditor to Express backend, it gives "MulterError: Unexpected field". This is my Express Route for image upload.

router.post('/archive', upload.single('file'), function(req, res, next) {
    if(!req.file) {
        return res.status(500).send({ message: 'Upload fail'});
    } else {
       html = "";
       html += "<script type='text/javascript'>";
       html += "    var funcNum = " + req.query.CKEditorFuncNum + ";";
       html += "    var url     = \"/public/images/" + req.file.filename + "\";";
       html += "    var message = \"Uploaded file successfully\";";
       html += "";
       html += "    window.parent.CKEDITOR.tools.callFunction(funcNum, url, message);";
       html += "</script>";

      res.send(html);
        //req.body.imageUrl = 'http://public/images/' + req.file.filename;
        Gallery.create(req.body, function (err, gallery) {
            if (err) {
                console.log(err);
                return next(err);
            }
            res.json(gallery);
        });
    }
});

And this is the angular code I'm using in my component for saving image to the backend.

import * as ClassicEditor from '@ckeditor/ckeditor5-build-classic';

public editor = ClassicEditor;

    public config:any = {
    ckfinder: {
      options: {
          resourceType: 'Images'
      },
      uploadUrl: 'http://localhost:3000/gallery/archive/'
    }
  }

I think the problem is with my uploadUrl but I don't know what it is. Can someone please give pointers in the right direction? Any help is greatly appreciated. Thank You.

EDIT

My Multer Configuration:

const storage = multer.diskStorage({
    destination: (req, file, cb) => {
      cb(null, './public/images');
    },
    filename: (req, file, cb) => {
      //console.log(file);
      var filetype = '';
      if(file.mimetype === 'image/gif') {
        filetype = 'gif';
      }
      if(file.mimetype === 'image/png') {
        filetype = 'png';
      }
      if(file.mimetype === 'image/jpeg') {
        filetype = 'jpg';
      }
      cb(null, 'image-' + Date.now() + '.' + filetype);
    }
});

const upload = multer({storage: storage});
Mohid
  • 103
  • 1
  • 4
  • 13

1 Answers1

1

This is the error that tells that the fieldName is not matched. You have specified in the beckend that the fieldname is 'file', so when you are sending image to the backend, you need to specify the same name 'file' in the frontend.

Or you can change your backend code from upload.single('file') to upload.any().

NeNaD
  • 18,172
  • 8
  • 47
  • 89
  • I did as you suggested and switched to upload.any(). Now the image gets saved in the public/images folder when I upload it with CKEditor, but it gives me a 500 internal server error. And the image does not show in the component. The Sever returns a fieldname of 'upload' for the images when I console.log it. – Mohid Apr 06 '21 at 15:09
  • Try `console.log('Uploaded Image: ', req.file)` and check if you are sending the correct `url` as response. – NeNaD Apr 06 '21 at 15:38
  • The console.log returns nothing. I only get this error in the browser: POST http://localhost:3000/gallery/archive/ 500 (Internal Server Error) – Mohid Apr 06 '21 at 15:48
  • Can you copy your `Multer` configuration here? And do the `console.log()` after the `router.post('/archive', upload.single('file'), function(req, res, next) {` to check if it is executed. – NeNaD Apr 06 '21 at 16:27
  • I console.logged right after `router.post('/archive', upload.any(), function(req, res, next) {` and it returns undefined – Mohid Apr 06 '21 at 16:39
  • Ok, try `console.log('Uploaded Images: ', req.files)`... If you are uploading multiple images then they will be populated in `req.files` and not in `req.file` property. – NeNaD Apr 06 '21 at 16:42
  • I am only trying to upload one image so far. I haven't tried to upload multiple images. – Mohid Apr 06 '21 at 17:04
  • Yeah, but maybe that CKEditor are sending an array of images that have only one image. Try `console.log(req.files)`. – NeNaD Apr 06 '21 at 17:29
  • Yes CKEditor is sending an array of images when I console.logged it. – Mohid Apr 06 '21 at 17:39
  • That is why you have an error. You are using `req.file.filename` and `req.file` does not exist. You should change `req.file.filename` to `req.files[0].filename` if you are uploading only one image. Also in `if` statement, change `req.file` to `req.files` – NeNaD Apr 06 '21 at 17:43
  • Now it's giving a new error: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client :( – Mohid Apr 06 '21 at 17:50
  • Check this: https://stackoverflow.com/questions/7042340/error-cant-set-headers-after-they-are-sent-to-the-client – NeNaD Apr 06 '21 at 17:57
  • It is because when you do `res.send(html)`, the response will be send. And you are trying to send it again after with `res.json(gallery);` – NeNaD Apr 06 '21 at 17:59
  • So, I removed the res.json(gallery) option. Now there are no more errors. No errors in the console or browser. The image I upload gets saved to the public/images folder, but the browser still refuses to upload the image. It says: "localhost: 4200 Cannot upload file." Is this a problem with the uploadUrl I am providing in ckifnder?? – Mohid Apr 07 '21 at 10:25